summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-03-12 14:11:15 +0100
committerSimon Hausmann <simon.hausmann@nokia.com>2012-03-12 14:11:15 +0100
commitdd91e772430dc294e3bf478c119ef8d43c0a3358 (patch)
tree6f33ce4d5872a5691e0291eb45bf6ab373a5f567 /Source/JavaScriptCore
parentad0d549d4cc13433f77c1ac8f0ab379c83d93f28 (diff)
downloadqtwebkit-dd91e772430dc294e3bf478c119ef8d43c0a3358.tar.gz
Imported WebKit commit 3db4eb1820ac8fb03065d7ea73a4d9db1e8fea1a (http://svn.webkit.org/repository/webkit/trunk@110422)
This includes build fixes for the latest qtbase/qtdeclarative as well as the final QML2 API.
Diffstat (limited to 'Source/JavaScriptCore')
-rw-r--r--Source/JavaScriptCore/API/JSObjectRef.cpp2
-rw-r--r--Source/JavaScriptCore/API/tests/JSNode.c2
-rw-r--r--Source/JavaScriptCore/API/tests/JSNodeList.c2
-rw-r--r--Source/JavaScriptCore/CMakeLists.txt6
-rw-r--r--Source/JavaScriptCore/ChangeLog3469
-rw-r--r--Source/JavaScriptCore/Configurations/Base.xcconfig7
-rw-r--r--Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig10
-rw-r--r--Source/JavaScriptCore/Configurations/JavaScriptCore.xcconfig2
-rw-r--r--Source/JavaScriptCore/Configurations/TestRegExp.xcconfig30
-rw-r--r--Source/JavaScriptCore/Configurations/ToolExecutable.xcconfig (renamed from Source/JavaScriptCore/Configurations/TestAPI.xcconfig)2
-rw-r--r--Source/JavaScriptCore/Configurations/Version.xcconfig4
-rw-r--r--Source/JavaScriptCore/GNUmakefile.list.am14
-rw-r--r--Source/JavaScriptCore/JSCTypedArrayStubs.h2
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.sln33
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def9
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj4
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make3
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.vcproj13
-rwxr-xr-xSource/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/build-generated-files.sh10
-rwxr-xr-xSource/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/copy-files.cmd149
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCoreSubmit.sln73
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj298
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGenerated.make13
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGenerated.vcproj95
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGeneratedCommon.vsprops14
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGeneratedDebug.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGeneratedDebugAll.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGeneratedDebugCairoCFLite.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGeneratedProduction.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGeneratedRelease.vsprops (renamed from Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFReleasePGO.vsprops)4
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGeneratedReleaseCairoCFLite.vsprops8
-rwxr-xr-xSource/JavaScriptCore/JavaScriptCore.vcproj/WTF/build-generated-files.sh11
-rwxr-xr-xSource/JavaScriptCore/JavaScriptCore.vcproj/WTF/copy-files.cmd37
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/work-around-vs-dependency-tracking-bugs.py (renamed from Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/work-around-vs-dependency-tracking-bugs.py)0
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jsc.vcproj8
-rwxr-xr-xSource/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExp.vcproj8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj419
-rw-r--r--Source/JavaScriptCore/KeywordLookupGenerator.py3
-rw-r--r--Source/JavaScriptCore/Target.pri3
-rw-r--r--Source/JavaScriptCore/assembler/ARMAssembler.cpp4
-rw-r--r--Source/JavaScriptCore/assembler/ARMAssembler.h3
-rw-r--r--Source/JavaScriptCore/assembler/ARMv7Assembler.h18
-rw-r--r--Source/JavaScriptCore/assembler/AbstractMacroAssembler.h61
-rw-r--r--Source/JavaScriptCore/assembler/AssemblerBuffer.h5
-rw-r--r--Source/JavaScriptCore/assembler/AssemblerBufferWithConstantPool.h4
-rw-r--r--Source/JavaScriptCore/assembler/LinkBuffer.h26
-rw-r--r--Source/JavaScriptCore/assembler/MIPSAssembler.h5
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssembler.h552
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerARM.h43
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h71
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h16
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h47
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerSH4.h50
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerX86.h14
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h59
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h43
-rw-r--r--Source/JavaScriptCore/assembler/SH4Assembler.h5
-rw-r--r--Source/JavaScriptCore/assembler/X86Assembler.h32
-rw-r--r--Source/JavaScriptCore/bytecode/CodeBlock.cpp104
-rw-r--r--Source/JavaScriptCore/bytecode/CodeBlock.h133
-rw-r--r--Source/JavaScriptCore/bytecode/CodeType.h17
-rw-r--r--Source/JavaScriptCore/bytecode/ExecutionCounter.cpp165
-rw-r--r--Source/JavaScriptCore/bytecode/ExecutionCounter.h83
-rw-r--r--Source/JavaScriptCore/bytecode/Opcode.h1
-rw-r--r--Source/JavaScriptCore/bytecode/PredictedType.cpp11
-rw-r--r--Source/JavaScriptCore/bytecode/PredictedType.h15
-rw-r--r--Source/JavaScriptCore/bytecode/SamplingTool.cpp4
-rw-r--r--Source/JavaScriptCore/bytecode/SamplingTool.h2
-rw-r--r--Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp15
-rw-r--r--Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h9
-rw-r--r--Source/JavaScriptCore/bytecompiler/Label.h15
-rw-r--r--Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp14
-rw-r--r--Source/JavaScriptCore/dfg/DFGAbstractState.cpp170
-rw-r--r--Source/JavaScriptCore/dfg/DFGAbstractState.h12
-rw-r--r--Source/JavaScriptCore/dfg/DFGAbstractValue.h5
-rw-r--r--Source/JavaScriptCore/dfg/DFGArithNodeFlagsInferencePhase.cpp17
-rw-r--r--Source/JavaScriptCore/dfg/DFGBasicBlock.h9
-rw-r--r--Source/JavaScriptCore/dfg/DFGByteCodeCache.h9
-rw-r--r--Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp230
-rw-r--r--Source/JavaScriptCore/dfg/DFGCCallHelpers.h14
-rw-r--r--Source/JavaScriptCore/dfg/DFGCFAPhase.cpp10
-rw-r--r--Source/JavaScriptCore/dfg/DFGCSEPhase.cpp163
-rw-r--r--Source/JavaScriptCore/dfg/DFGCapabilities.h34
-rw-r--r--Source/JavaScriptCore/dfg/DFGCommon.h7
-rw-r--r--Source/JavaScriptCore/dfg/DFGDriver.cpp9
-rw-r--r--Source/JavaScriptCore/dfg/DFGGraph.cpp25
-rw-r--r--Source/JavaScriptCore/dfg/DFGGraph.h41
-rw-r--r--Source/JavaScriptCore/dfg/DFGJITCompiler.cpp22
-rw-r--r--Source/JavaScriptCore/dfg/DFGJITCompiler.h9
-rw-r--r--Source/JavaScriptCore/dfg/DFGNode.cpp81
-rw-r--r--Source/JavaScriptCore/dfg/DFGNode.h282
-rw-r--r--Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp36
-rw-r--r--Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp28
-rw-r--r--Source/JavaScriptCore/dfg/DFGOperations.cpp69
-rw-r--r--Source/JavaScriptCore/dfg/DFGOperations.h8
-rw-r--r--Source/JavaScriptCore/dfg/DFGPhase.cpp2
-rw-r--r--Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp52
-rw-r--r--Source/JavaScriptCore/dfg/DFGRedundantPhiEliminationPhase.cpp176
-rw-r--r--Source/JavaScriptCore/dfg/DFGRedundantPhiEliminationPhase.h49
-rw-r--r--Source/JavaScriptCore/dfg/DFGScoreBoard.h24
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp143
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h101
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp265
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp251
-rw-r--r--Source/JavaScriptCore/dfg/DFGVirtualRegisterAllocationPhase.cpp79
-rw-r--r--Source/JavaScriptCore/heap/CopiedAllocator.h3
-rw-r--r--Source/JavaScriptCore/heap/CopiedBlock.h19
-rw-r--r--Source/JavaScriptCore/heap/CopiedSpace.cpp4
-rw-r--r--Source/JavaScriptCore/heap/CopiedSpace.h3
-rw-r--r--Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h6
-rw-r--r--Source/JavaScriptCore/heap/DFGCodeBlocks.cpp4
-rw-r--r--Source/JavaScriptCore/heap/GCAssertions.h2
-rw-r--r--Source/JavaScriptCore/heap/HandleHeap.h8
-rw-r--r--Source/JavaScriptCore/heap/HandleStack.h4
-rw-r--r--Source/JavaScriptCore/heap/Heap.cpp4
-rw-r--r--Source/JavaScriptCore/heap/Heap.h4
-rw-r--r--Source/JavaScriptCore/heap/MarkedBlock.h2
-rw-r--r--Source/JavaScriptCore/heap/MarkedSpace.h2
-rw-r--r--Source/JavaScriptCore/heap/PassWeak.h6
-rw-r--r--Source/JavaScriptCore/heap/Strong.h2
-rw-r--r--Source/JavaScriptCore/heap/Weak.h2
-rw-r--r--Source/JavaScriptCore/interpreter/Interpreter.cpp121
-rw-r--r--Source/JavaScriptCore/jit/ExecutableAllocator.cpp117
-rw-r--r--Source/JavaScriptCore/jit/ExecutableAllocator.h16
-rw-r--r--Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp19
-rw-r--r--Source/JavaScriptCore/jit/HostCallReturnValue.cpp2
-rw-r--r--Source/JavaScriptCore/jit/JIT.cpp32
-rw-r--r--Source/JavaScriptCore/jit/JIT.h25
-rw-r--r--Source/JavaScriptCore/jit/JITArithmetic.cpp60
-rw-r--r--Source/JavaScriptCore/jit/JITArithmetic32_64.cpp48
-rw-r--r--Source/JavaScriptCore/jit/JITCall.cpp7
-rw-r--r--Source/JavaScriptCore/jit/JITCall32_64.cpp4
-rw-r--r--Source/JavaScriptCore/jit/JITCompilationEffort.h39
-rw-r--r--Source/JavaScriptCore/jit/JITDriver.h25
-rw-r--r--Source/JavaScriptCore/jit/JITExceptions.cpp3
-rw-r--r--Source/JavaScriptCore/jit/JITInlineMethods.h87
-rw-r--r--Source/JavaScriptCore/jit/JITOpcodes.cpp110
-rw-r--r--Source/JavaScriptCore/jit/JITOpcodes32_64.cpp28
-rw-r--r--Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp2
-rw-r--r--Source/JavaScriptCore/jit/JITStubCall.h12
-rw-r--r--Source/JavaScriptCore/jit/JITStubs.cpp38
-rw-r--r--Source/JavaScriptCore/jit/JITStubs.h24
-rw-r--r--Source/JavaScriptCore/jit/ThunkGenerators.cpp2
-rw-r--r--Source/JavaScriptCore/jsc.cpp4
-rw-r--r--Source/JavaScriptCore/llint/LLIntData.cpp15
-rw-r--r--Source/JavaScriptCore/llint/LLIntEntrypoints.cpp14
-rw-r--r--Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h18
-rw-r--r--Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp4
-rw-r--r--Source/JavaScriptCore/llint/LLIntSlowPaths.cpp135
-rw-r--r--Source/JavaScriptCore/llint/LLIntSlowPaths.h34
-rw-r--r--Source/JavaScriptCore/llint/LLIntThunks.cpp2
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter.asm1789
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter.h4
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm1653
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter64.asm1490
-rw-r--r--Source/JavaScriptCore/offlineasm/armv7.rb50
-rw-r--r--Source/JavaScriptCore/offlineasm/asm.rb13
-rw-r--r--Source/JavaScriptCore/offlineasm/ast.rb187
-rw-r--r--Source/JavaScriptCore/offlineasm/backends.rb18
-rw-r--r--Source/JavaScriptCore/offlineasm/generate_offset_extractor.rb5
-rw-r--r--Source/JavaScriptCore/offlineasm/instructions.rb8
-rw-r--r--Source/JavaScriptCore/offlineasm/offsets.rb12
-rw-r--r--Source/JavaScriptCore/offlineasm/parser.rb102
-rw-r--r--Source/JavaScriptCore/offlineasm/registers.rb8
-rw-r--r--Source/JavaScriptCore/offlineasm/self_hash.rb29
-rw-r--r--Source/JavaScriptCore/offlineasm/settings.rb2
-rw-r--r--Source/JavaScriptCore/offlineasm/transform.rb132
-rw-r--r--Source/JavaScriptCore/offlineasm/x86.rb510
-rw-r--r--Source/JavaScriptCore/parser/ASTBuilder.h49
-rw-r--r--Source/JavaScriptCore/parser/Lexer.cpp245
-rw-r--r--Source/JavaScriptCore/parser/Lexer.h26
-rw-r--r--Source/JavaScriptCore/parser/NodeConstructors.h15
-rw-r--r--Source/JavaScriptCore/parser/NodeInfo.h4
-rw-r--r--Source/JavaScriptCore/parser/Nodes.cpp85
-rw-r--r--Source/JavaScriptCore/parser/Nodes.h139
-rw-r--r--Source/JavaScriptCore/parser/Parser.cpp70
-rw-r--r--Source/JavaScriptCore/parser/Parser.h118
-rw-r--r--Source/JavaScriptCore/parser/ParserArena.cpp6
-rw-r--r--Source/JavaScriptCore/parser/ParserArena.h7
-rw-r--r--Source/JavaScriptCore/parser/ResultType.h27
-rw-r--r--Source/JavaScriptCore/parser/SourceProvider.h2
-rw-r--r--Source/JavaScriptCore/parser/SourceProviderCacheItem.h4
-rw-r--r--Source/JavaScriptCore/parser/SyntaxChecker.h7
-rw-r--r--Source/JavaScriptCore/runtime/Arguments.cpp13
-rw-r--r--Source/JavaScriptCore/runtime/Arguments.h2
-rw-r--r--Source/JavaScriptCore/runtime/ArrayPrototype.cpp236
-rw-r--r--Source/JavaScriptCore/runtime/ClassInfo.h2
-rw-r--r--Source/JavaScriptCore/runtime/CommonIdentifiers.h5
-rw-r--r--Source/JavaScriptCore/runtime/Completion.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/Error.cpp20
-rw-r--r--Source/JavaScriptCore/runtime/Executable.cpp43
-rw-r--r--Source/JavaScriptCore/runtime/Executable.h41
-rw-r--r--Source/JavaScriptCore/runtime/ExecutionHarness.h4
-rw-r--r--Source/JavaScriptCore/runtime/GCActivityCallbackCF.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/Identifier.cpp14
-rw-r--r--Source/JavaScriptCore/runtime/Identifier.h2
-rw-r--r--Source/JavaScriptCore/runtime/InitializeThreading.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/JSArray.cpp220
-rw-r--r--Source/JavaScriptCore/runtime/JSArray.h61
-rw-r--r--Source/JavaScriptCore/runtime/JSByteArray.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/JSByteArray.h2
-rw-r--r--Source/JavaScriptCore/runtime/JSCell.cpp13
-rw-r--r--Source/JavaScriptCore/runtime/JSCell.h2
-rw-r--r--Source/JavaScriptCore/runtime/JSDateMath.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/JSFunction.cpp77
-rw-r--r--Source/JavaScriptCore/runtime/JSFunction.h1
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalData.cpp9
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalData.h6
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/JSNotAnObject.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/JSNotAnObject.h2
-rw-r--r--Source/JavaScriptCore/runtime/JSONObject.cpp8
-rw-r--r--Source/JavaScriptCore/runtime/JSObject.cpp17
-rw-r--r--Source/JavaScriptCore/runtime/JSObject.h13
-rw-r--r--Source/JavaScriptCore/runtime/JSString.cpp10
-rw-r--r--Source/JavaScriptCore/runtime/JSStringBuilder.h2
-rw-r--r--Source/JavaScriptCore/runtime/JSValue.cpp82
-rw-r--r--Source/JavaScriptCore/runtime/JSValue.h5
-rw-r--r--Source/JavaScriptCore/runtime/JSVariableObject.h2
-rw-r--r--Source/JavaScriptCore/runtime/NumberPrototype.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/Options.cpp61
-rw-r--r--Source/JavaScriptCore/runtime/Options.h16
-rw-r--r--Source/JavaScriptCore/runtime/PropertyDescriptor.cpp16
-rw-r--r--Source/JavaScriptCore/runtime/PropertyDescriptor.h1
-rw-r--r--Source/JavaScriptCore/runtime/PropertySlot.cpp6
-rw-r--r--Source/JavaScriptCore/runtime/RegExp.cpp28
-rw-r--r--Source/JavaScriptCore/runtime/RegExpConstructor.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/RegExpMatchesArray.h4
-rw-r--r--Source/JavaScriptCore/runtime/RegExpObject.cpp121
-rw-r--r--Source/JavaScriptCore/runtime/RegExpObject.h48
-rw-r--r--Source/JavaScriptCore/runtime/RegExpPrototype.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/StringObject.cpp48
-rw-r--r--Source/JavaScriptCore/runtime/StringObject.h1
-rw-r--r--Source/JavaScriptCore/runtime/StringPrototype.cpp48
-rw-r--r--Source/JavaScriptCore/runtime/SymbolTable.h2
-rw-r--r--Source/JavaScriptCore/runtime/WriteBarrier.h2
-rw-r--r--Source/JavaScriptCore/tests/mozilla/ecma/Array/15.4.5.1-1.js4
-rw-r--r--Source/JavaScriptCore/tests/mozilla/ecma/LexicalConventions/7.7.4.js9
-rw-r--r--Source/JavaScriptCore/tests/mozilla/ecma/TypeConversion/9.3.1-3.js6
-rw-r--r--Source/JavaScriptCore/tests/mozilla/ecma_2/RegExp/constructor-001.js2
-rw-r--r--Source/JavaScriptCore/tests/mozilla/ecma_2/RegExp/function-001.js2
-rw-r--r--Source/JavaScriptCore/tests/mozilla/ecma_2/RegExp/hex-001.js3
-rw-r--r--Source/JavaScriptCore/tests/mozilla/ecma_2/RegExp/properties-001.js8
-rw-r--r--Source/JavaScriptCore/tests/mozilla/js1_2/regexp/hexadecimal.js2
-rw-r--r--Source/JavaScriptCore/tests/mozilla/js1_6/Array/regress-304828.js6
-rw-r--r--Source/JavaScriptCore/tools/CodeProfile.cpp2
-rw-r--r--Source/JavaScriptCore/tools/TieredMMapArray.h2
-rw-r--r--Source/JavaScriptCore/wscript2
-rw-r--r--Source/JavaScriptCore/wtf/AVLTree.h2
-rw-r--r--Source/JavaScriptCore/wtf/Alignment.h2
-rw-r--r--Source/JavaScriptCore/wtf/AlwaysInline.h2
-rw-r--r--Source/JavaScriptCore/wtf/ArrayBuffer.h2
-rw-r--r--Source/JavaScriptCore/wtf/ArrayBufferView.h6
-rw-r--r--Source/JavaScriptCore/wtf/Assertions.cpp9
-rw-r--r--Source/JavaScriptCore/wtf/Assertions.h2
-rw-r--r--Source/JavaScriptCore/wtf/Atomics.h12
-rw-r--r--Source/JavaScriptCore/wtf/Bitmap.h6
-rw-r--r--Source/JavaScriptCore/wtf/BoundsCheckedPointer.h4
-rw-r--r--Source/JavaScriptCore/wtf/CMakeLists.txt7
-rw-r--r--Source/JavaScriptCore/wtf/CheckedArithmetic.h4
-rw-r--r--Source/JavaScriptCore/wtf/DateMath.cpp11
-rw-r--r--Source/JavaScriptCore/wtf/Deque.h4
-rw-r--r--Source/JavaScriptCore/wtf/ExportMacros.h10
-rw-r--r--Source/JavaScriptCore/wtf/FastAllocBase.h8
-rw-r--r--Source/JavaScriptCore/wtf/FastMalloc.h4
-rw-r--r--Source/JavaScriptCore/wtf/Float32Array.h2
-rw-r--r--Source/JavaScriptCore/wtf/Float64Array.h2
-rw-r--r--Source/JavaScriptCore/wtf/Functional.h8
-rw-r--r--Source/JavaScriptCore/wtf/HashCountedSet.h6
-rw-r--r--Source/JavaScriptCore/wtf/HashFunctions.h2
-rw-r--r--Source/JavaScriptCore/wtf/HashMap.h4
-rw-r--r--Source/JavaScriptCore/wtf/HashSet.h4
-rw-r--r--Source/JavaScriptCore/wtf/HashTable.h22
-rw-r--r--Source/JavaScriptCore/wtf/HashTraits.h6
-rw-r--r--Source/JavaScriptCore/wtf/Int16Array.h2
-rw-r--r--Source/JavaScriptCore/wtf/Int32Array.h2
-rw-r--r--Source/JavaScriptCore/wtf/Int8Array.h2
-rw-r--r--Source/JavaScriptCore/wtf/IntegralTypedArrayBase.h2
-rw-r--r--Source/JavaScriptCore/wtf/ListHashSet.h6
-rw-r--r--Source/JavaScriptCore/wtf/MainThread.h2
-rw-r--r--Source/JavaScriptCore/wtf/MetaAllocator.cpp3
-rw-r--r--Source/JavaScriptCore/wtf/MetaAllocator.h19
-rw-r--r--Source/JavaScriptCore/wtf/Noncopyable.h2
-rw-r--r--Source/JavaScriptCore/wtf/OwnArrayPtr.h8
-rw-r--r--Source/JavaScriptCore/wtf/OwnPtr.h8
-rw-r--r--Source/JavaScriptCore/wtf/PackedIntVector.h2
-rw-r--r--Source/JavaScriptCore/wtf/ParallelJobs.h12
-rw-r--r--Source/JavaScriptCore/wtf/PassOwnArrayPtr.h6
-rw-r--r--Source/JavaScriptCore/wtf/PassOwnPtr.h8
-rw-r--r--Source/JavaScriptCore/wtf/PassRefPtr.h4
-rw-r--r--Source/JavaScriptCore/wtf/PassTraits.h4
-rw-r--r--Source/JavaScriptCore/wtf/Platform.h29
-rw-r--r--Source/JavaScriptCore/wtf/PossiblyNull.h2
-rw-r--r--Source/JavaScriptCore/wtf/RefCounted.h23
-rw-r--r--Source/JavaScriptCore/wtf/RefCountedArray.h165
-rw-r--r--Source/JavaScriptCore/wtf/RefCountedLeakCounter.h4
-rw-r--r--Source/JavaScriptCore/wtf/RefPtr.h4
-rw-r--r--Source/JavaScriptCore/wtf/RetainPtr.h6
-rw-r--r--Source/JavaScriptCore/wtf/SimpleStats.h107
-rw-r--r--Source/JavaScriptCore/wtf/Spectrum.h4
-rw-r--r--Source/JavaScriptCore/wtf/StdLibExtras.h4
-rw-r--r--Source/JavaScriptCore/wtf/TCPageMap.h2
-rw-r--r--Source/JavaScriptCore/wtf/TCSpinLock.h2
-rw-r--r--Source/JavaScriptCore/wtf/TemporaryChange.h2
-rw-r--r--Source/JavaScriptCore/wtf/ThreadSafeRefCounted.h2
-rw-r--r--Source/JavaScriptCore/wtf/Threading.h2
-rw-r--r--Source/JavaScriptCore/wtf/ThreadingPrimitives.h2
-rw-r--r--Source/JavaScriptCore/wtf/TypeTraits.h2
-rw-r--r--Source/JavaScriptCore/wtf/TypedArrayBase.h4
-rw-r--r--Source/JavaScriptCore/wtf/Uint16Array.h2
-rw-r--r--Source/JavaScriptCore/wtf/Uint32Array.h2
-rw-r--r--Source/JavaScriptCore/wtf/Uint8Array.h2
-rw-r--r--Source/JavaScriptCore/wtf/Uint8ClampedArray.h2
-rw-r--r--Source/JavaScriptCore/wtf/UnusedParam.h2
-rw-r--r--Source/JavaScriptCore/wtf/Vector.h18
-rw-r--r--Source/JavaScriptCore/wtf/VectorTraits.h6
-rw-r--r--Source/JavaScriptCore/wtf/WTFThreadData.cpp21
-rw-r--r--Source/JavaScriptCore/wtf/dtoa/double-conversion.h2
-rw-r--r--Source/JavaScriptCore/wtf/dtoa/utils.h2
-rw-r--r--Source/JavaScriptCore/wtf/gobject/GRefPtr.cpp26
-rw-r--r--Source/JavaScriptCore/wtf/gobject/GRefPtr.h9
-rw-r--r--Source/JavaScriptCore/wtf/gobject/GTypedefs.h2
-rw-r--r--Source/JavaScriptCore/wtf/gobject/GlibUtilities.h4
-rw-r--r--Source/JavaScriptCore/wtf/text/AtomicString.h6
-rw-r--r--Source/JavaScriptCore/wtf/text/AtomicStringImpl.h2
-rw-r--r--Source/JavaScriptCore/wtf/text/CString.h6
-rw-r--r--Source/JavaScriptCore/wtf/text/StringConcatenate.h4
-rw-r--r--Source/JavaScriptCore/wtf/text/StringHash.h4
-rw-r--r--Source/JavaScriptCore/wtf/text/WTFString.h6
-rw-r--r--Source/JavaScriptCore/wtf/unicode/CharacterNames.h2
-rw-r--r--Source/JavaScriptCore/wtf/unicode/UTF8.h2
-rw-r--r--Source/JavaScriptCore/wtf/unicode/glib/UnicodeGLib.h6
-rw-r--r--Source/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h4
-rw-r--r--Source/JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.h4
-rw-r--r--Source/JavaScriptCore/wtf/url/api/ParsedURL.cpp29
-rw-r--r--Source/JavaScriptCore/wtf/url/api/ParsedURL.h32
-rw-r--r--Source/JavaScriptCore/wtf/url/api/URLString.h2
-rw-r--r--Source/JavaScriptCore/wtf/wince/FastMallocWinCE.h2
-rw-r--r--Source/JavaScriptCore/yarr/Yarr.h3
-rw-r--r--Source/JavaScriptCore/yarr/YarrInterpreter.cpp162
-rw-r--r--Source/JavaScriptCore/yarr/YarrInterpreter.h2
-rw-r--r--Source/JavaScriptCore/yarr/YarrJIT.cpp6
-rw-r--r--Source/JavaScriptCore/yarr/YarrParser.h8
343 files changed, 14208 insertions, 4998 deletions
diff --git a/Source/JavaScriptCore/API/JSObjectRef.cpp b/Source/JavaScriptCore/API/JSObjectRef.cpp
index cd8d7159e..17329ad87 100644
--- a/Source/JavaScriptCore/API/JSObjectRef.cpp
+++ b/Source/JavaScriptCore/API/JSObjectRef.cpp
@@ -312,7 +312,7 @@ void JSObjectSetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned p
JSObject* jsObject = toJS(object);
JSValue jsValue = toJS(exec, value);
- jsObject->methodTable()->putByIndex(jsObject, exec, propertyIndex, jsValue);
+ jsObject->methodTable()->putByIndex(jsObject, exec, propertyIndex, jsValue, false);
if (exec->hadException()) {
if (exception)
*exception = toRef(exec, exec->exception());
diff --git a/Source/JavaScriptCore/API/tests/JSNode.c b/Source/JavaScriptCore/API/tests/JSNode.c
index d9ac0a913..052c88a02 100644
--- a/Source/JavaScriptCore/API/tests/JSNode.c
+++ b/Source/JavaScriptCore/API/tests/JSNode.c
@@ -30,7 +30,7 @@
#include "JSValueRef.h"
#include "Node.h"
#include "NodeList.h"
-#include "UnusedParam.h"
+#include <wtf/UnusedParam.h>
#include <wtf/Assertions.h>
static JSValueRef JSNode_appendChild(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
diff --git a/Source/JavaScriptCore/API/tests/JSNodeList.c b/Source/JavaScriptCore/API/tests/JSNodeList.c
index bc4a8ad99..0d194845e 100644
--- a/Source/JavaScriptCore/API/tests/JSNodeList.c
+++ b/Source/JavaScriptCore/API/tests/JSNodeList.c
@@ -27,7 +27,7 @@
#include "JSNodeList.h"
#include "JSObjectRef.h"
#include "JSValueRef.h"
-#include "UnusedParam.h"
+#include <wtf/UnusedParam.h>
#include <wtf/Assertions.h>
static JSValueRef JSNodeList_item(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
diff --git a/Source/JavaScriptCore/CMakeLists.txt b/Source/JavaScriptCore/CMakeLists.txt
index 2afcbdc65..d4a51d214 100644
--- a/Source/JavaScriptCore/CMakeLists.txt
+++ b/Source/JavaScriptCore/CMakeLists.txt
@@ -40,6 +40,7 @@ SET(JavaScriptCore_SOURCES
bytecode/CallLinkStatus.cpp
bytecode/CodeBlock.cpp
bytecode/DFGExitProfile.cpp
+ bytecode/ExecutionCounter.cpp
bytecode/GetByIdStatus.cpp
bytecode/JumpTable.cpp
bytecode/LazyOperandValueProfile.cpp
@@ -67,6 +68,7 @@ SET(JavaScriptCore_SOURCES
dfg/DFGDriver.cpp
dfg/DFGGraph.cpp
dfg/DFGJITCompiler.cpp
+ dfg/DFGNode.cpp
dfg/DFGOSREntry.cpp
dfg/DFGOSRExit.cpp
dfg/DFGOSRExitCompiler.cpp
@@ -75,6 +77,7 @@ SET(JavaScriptCore_SOURCES
dfg/DFGOperations.cpp
dfg/DFGPhase.cpp
dfg/DFGPredictionPropagationPhase.cpp
+ dfg/DFGRedundantPhiEliminationPhase.cpp
dfg/DFGRepatch.cpp
dfg/DFGSpeculativeJIT.cpp
dfg/DFGSpeculativeJIT32_64.cpp
@@ -300,6 +303,7 @@ INCLUDE_DIRECTORIES(${JavaScriptCore_INCLUDE_DIRECTORIES})
ADD_DEFINITIONS(-DBUILDING_JavaScriptCore)
ADD_LIBRARY(${JavaScriptCore_LIBRARY_NAME} ${JavaScriptCore_LIBRARY_TYPE} ${JavaScriptCore_HEADERS} ${JavaScriptCore_SOURCES})
TARGET_LINK_LIBRARIES(${JavaScriptCore_LIBRARY_NAME} ${JavaScriptCore_LIBRARIES})
+SET_TARGET_PROPERTIES(${JavaScriptCore_LIBRARY_NAME} PROPERTIES LINK_INTERFACE_LIBRARIES "")
IF (JavaScriptCore_LINK_FLAGS)
ADD_TARGET_PROPERTIES(${JavaScriptCore_LIBRARY_NAME} LINK_FLAGS "${JavaScriptCore_LINK_FLAGS}")
@@ -307,5 +311,5 @@ ENDIF ()
IF (SHARED_CORE)
SET_TARGET_PROPERTIES(${JavaScriptCore_LIBRARY_NAME} PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR})
- INSTALL(TARGETS ${JavaScriptCore_LIBRARY_NAME} DESTINATION lib)
+ INSTALL(TARGETS ${JavaScriptCore_LIBRARY_NAME} DESTINATION "${LIB_INSTALL_DIR}")
ENDIF ()
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index 87b921f0f..0092392f0 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,3472 @@
+2012-03-12 Filip Pizlo <fpizlo@apple.com>
+
+ All DFG nodes should have a mutable set of flags
+ https://bugs.webkit.org/show_bug.cgi?id=80779
+ <rdar://problem/11026218>
+
+ Reviewed by Gavin Barraclough.
+
+ Got rid of NodeId, and placed all of the flags that distinguished NodeId
+ from NodeType into a separate Node::flags field. Combined what was previously
+ ArithNodeFlags into Node::flags.
+
+ In the process of debugging, I found that the debug support in the virtual
+ register allocator was lacking, so I improved it. I also realized that the
+ virtual register allocator was assuming that the nodes in a basic block were
+ contiguous, which is no longer the case. So I fixed that. The fix also made
+ it natural to have more extreme assertions, so I added them. I suspect this
+ will make it easier to catch virtual register allocation bugs in the future.
+
+ This is mostly performance neutral; if anything it looks like a slight
+ speed-up.
+
+ This patch does leave some work for future refactorings; for example, Node::op
+ is unencapsulated. This was already the case, though now it feels even more
+ like it should be. I avoided doing that because this patch has already grown
+ way bigger than I wanted.
+
+ Finally, this patch creates a DFGNode.cpp file and makes a slight effort to
+ move some unnecessarily inline stuff out of DFGNode.h.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * dfg/DFGArithNodeFlagsInferencePhase.cpp:
+ (JSC::DFG::ArithNodeFlagsInferencePhase::propagate):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::addToGraph):
+ (JSC::DFG::ByteCodeParser::makeSafe):
+ (JSC::DFG::ByteCodeParser::makeDivSafe):
+ (JSC::DFG::ByteCodeParser::handleMinMax):
+ (JSC::DFG::ByteCodeParser::handleIntrinsic):
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGCFAPhase.cpp:
+ (JSC::DFG::CFAPhase::performBlockCFA):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::endIndexForPureCSE):
+ (JSC::DFG::CSEPhase::pureCSE):
+ (JSC::DFG::CSEPhase::clobbersWorld):
+ (JSC::DFG::CSEPhase::impureCSE):
+ (JSC::DFG::CSEPhase::setReplacement):
+ (JSC::DFG::CSEPhase::eliminate):
+ (JSC::DFG::CSEPhase::performNodeCSE):
+ (JSC::DFG::CSEPhase::performBlockCSE):
+ (CSEPhase):
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::Graph::opName):
+ (JSC::DFG::Graph::dump):
+ (DFG):
+ * dfg/DFGNode.cpp: Added.
+ (DFG):
+ (JSC::DFG::arithNodeFlagsAsString):
+ * dfg/DFGNode.h:
+ (DFG):
+ (JSC::DFG::nodeUsedAsNumber):
+ (JSC::DFG::nodeCanTruncateInteger):
+ (JSC::DFG::nodeCanIgnoreNegativeZero):
+ (JSC::DFG::nodeMayOverflow):
+ (JSC::DFG::nodeCanSpeculateInteger):
+ (JSC::DFG::defaultFlags):
+ (JSC::DFG::Node::Node):
+ (Node):
+ (JSC::DFG::Node::setOpAndDefaultFlags):
+ (JSC::DFG::Node::mustGenerate):
+ (JSC::DFG::Node::arithNodeFlags):
+ (JSC::DFG::Node::setArithNodeFlag):
+ (JSC::DFG::Node::mergeArithNodeFlags):
+ (JSC::DFG::Node::hasResult):
+ (JSC::DFG::Node::hasInt32Result):
+ (JSC::DFG::Node::hasNumberResult):
+ (JSC::DFG::Node::hasJSResult):
+ (JSC::DFG::Node::hasBooleanResult):
+ (JSC::DFG::Node::isJump):
+ (JSC::DFG::Node::isBranch):
+ (JSC::DFG::Node::isTerminal):
+ (JSC::DFG::Node::child1):
+ (JSC::DFG::Node::child2):
+ (JSC::DFG::Node::child3):
+ (JSC::DFG::Node::firstChild):
+ (JSC::DFG::Node::numChildren):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ (JSC::DFG::PredictionPropagationPhase::vote):
+ (JSC::DFG::PredictionPropagationPhase::fixupNode):
+ * dfg/DFGScoreBoard.h:
+ (ScoreBoard):
+ (JSC::DFG::ScoreBoard::~ScoreBoard):
+ (JSC::DFG::ScoreBoard::assertClear):
+ (JSC::DFG::ScoreBoard::use):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::useChildren):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGVirtualRegisterAllocationPhase.cpp:
+ (JSC::DFG::VirtualRegisterAllocationPhase::run):
+
+2012-03-10 Filip Pizlo <fpizlo@apple.com>
+
+ LLInt should support JSVALUE64
+ https://bugs.webkit.org/show_bug.cgi?id=79609
+ <rdar://problem/10063437>
+
+ Reviewed by Gavin Barraclough and Oliver Hunt.
+
+ Ported the LLInt, which previously only worked on 32-bit, to 64-bit. This
+ patch moves a fair bit of code from LowLevelInterpreter32_64.asm to the common
+ file, LowLevelInterpreter.asm. About 1/3 of the LLInt did not have to be
+ specialized for value representation.
+
+ Also made some minor changes to offlineasm and the slow-paths.
+
+ * llint/LLIntData.cpp:
+ (JSC::LLInt::Data::performAssertions):
+ * llint/LLIntEntrypoints.cpp:
+ * llint/LLIntSlowPaths.cpp:
+ (LLInt):
+ (JSC::LLInt::llint_trace_value):
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ (JSC::LLInt::jitCompileAndSetHeuristics):
+ * llint/LLIntSlowPaths.h:
+ (LLInt):
+ (SlowPathReturnType):
+ (JSC::LLInt::SlowPathReturnType::SlowPathReturnType):
+ (JSC::LLInt::encodeResult):
+ * llint/LLIntThunks.cpp:
+ * llint/LowLevelInterpreter.asm:
+ * llint/LowLevelInterpreter32_64.asm:
+ * llint/LowLevelInterpreter64.asm:
+ * offlineasm/armv7.rb:
+ * offlineasm/asm.rb:
+ * offlineasm/ast.rb:
+ * offlineasm/backends.rb:
+ * offlineasm/instructions.rb:
+ * offlineasm/parser.rb:
+ * offlineasm/registers.rb:
+ * offlineasm/transform.rb:
+ * offlineasm/x86.rb:
+ * wtf/Platform.h:
+
+2012-03-10 Yong Li <yoli@rim.com>
+
+ Web Worker crashes with WX_EXCLUSIVE
+ https://bugs.webkit.org/show_bug.cgi?id=80532
+
+ Let each JS global object own a meta allocator
+ for WX_EXCLUSIVE to avoid conflicts from Web Worker.
+ Also fix a mutex leak in MetaAllocator's dtor.
+
+ Reviewed by Filip Pizlo.
+
+ * jit/ExecutableAllocator.cpp:
+ (JSC::DemandExecutableAllocator::DemandExecutableAllocator):
+ (JSC::DemandExecutableAllocator::~DemandExecutableAllocator):
+ (JSC::DemandExecutableAllocator::bytesAllocatedByAllAllocators):
+ (DemandExecutableAllocator):
+ (JSC::DemandExecutableAllocator::bytesCommittedByAllocactors):
+ (JSC::DemandExecutableAllocator::dumpProfileFromAllAllocators):
+ (JSC::DemandExecutableAllocator::allocateNewSpace):
+ (JSC::DemandExecutableAllocator::allocators):
+ (JSC::DemandExecutableAllocator::allocatorsMutex):
+ (JSC):
+ (JSC::ExecutableAllocator::initializeAllocator):
+ (JSC::ExecutableAllocator::ExecutableAllocator):
+ (JSC::ExecutableAllocator::underMemoryPressure):
+ (JSC::ExecutableAllocator::memoryPressureMultiplier):
+ (JSC::ExecutableAllocator::allocate):
+ (JSC::ExecutableAllocator::committedByteCount):
+ (JSC::ExecutableAllocator::dumpProfile):
+ * jit/ExecutableAllocator.h:
+ (JSC):
+ (ExecutableAllocator):
+ (JSC::ExecutableAllocator::allocator):
+ * wtf/MetaAllocator.h:
+ (WTF::MetaAllocator::~MetaAllocator): Finalize the spin lock.
+ * wtf/TCSpinLock.h:
+ (TCMalloc_SpinLock::Finalize): Add empty Finalize() to some implementations.
+
+2012-03-09 Gavin Barraclough <barraclough@apple.com>
+
+ Object.freeze broken on latest Nightly
+ https://bugs.webkit.org/show_bug.cgi?id=80577
+
+ Reviewed by Oliver Hunt.
+
+ The problem here is that deleteProperty rejects deletion of prototype.
+ This is correct in most cases, however defineOwnPropery is presently
+ implemented internally to ensure the attributes change by deleting the
+ old property, and creating a new one.
+
+ * runtime/JSFunction.cpp:
+ (JSC::JSFunction::deleteProperty):
+ - If deletePropery is called via defineOwnPropery, allow old prototype to be removed.
+
+2012-03-09 Gavin Barraclough <barraclough@apple.com>
+
+ Array.prototype.toLocaleString visits elements in wrong order under certain conditions
+ https://bugs.webkit.org/show_bug.cgi?id=80663
+
+ Reviewed by Michael Saboff.
+
+ The bug here is actually that we're continuing to process the array after an exception
+ has been thrown, and that the second value throw is overriding the first.
+
+ * runtime/ArrayPrototype.cpp:
+ (JSC::arrayProtoFuncToLocaleString):
+
+2012-03-09 Ryosuke Niwa <rniwa@webkit.org>
+
+ WebKit compiled by gcc (Xcode 3.2.6) hangs while running DOM/Accessors.html
+ https://bugs.webkit.org/show_bug.cgi?id=80080
+
+ Reviewed by Filip Pizlo.
+
+ * bytecode/SamplingTool.cpp:
+ (JSC::SamplingRegion::Locker::Locker):
+ (JSC::SamplingRegion::Locker::~Locker):
+ * bytecode/SamplingTool.h:
+ (JSC::SamplingRegion::exchangeCurrent):
+ * wtf/Atomics.h:
+ (WTF):
+ (WTF::weakCompareAndSwap):
+ (WTF::weakCompareAndSwapUIntPtr):
+
+2012-03-09 Gavin Barraclough <barraclough@apple.com>
+
+ REGRESSION: Date.parse("Tue Nov 23 20:40:05 2010 GMT") returns NaN
+ https://bugs.webkit.org/show_bug.cgi?id=49989
+
+ Reviewed by Oliver Hunt.
+
+ Patch originally by chris reiss <christopher.reiss@nokia.com>,
+ allow the year to appear before the timezone in date strings.
+
+ * wtf/DateMath.cpp:
+ (WTF::parseDateFromNullTerminatedCharacters):
+
+2012-03-09 Mark Rowe <mrowe@apple.com>
+
+ Ensure that the WTF headers are copied at installhdrs time.
+
+ Reviewed by Dan Bernstein and Jessie Berlin.
+
+ * Configurations/JavaScriptCore.xcconfig: Set INSTALLHDRS_SCRIPT_PHASE = YES
+ so that our script phases are invoked at installhdrs time. The only one that
+ does any useful work at that time is the one that installs WTF headers.
+
+2012-03-09 Jon Lee <jonlee@apple.com>
+
+ Add support for ENABLE(LEGACY_NOTIFICATIONS)
+ https://bugs.webkit.org/show_bug.cgi?id=80497
+
+ Reviewed by Adam Barth.
+
+ Prep for b80472: Update API for Web Notifications
+ * Configurations/FeatureDefines.xcconfig:
+
+2012-03-09 Ashod Nakashian <ashodnakashian@yahoo.com>
+
+ Bash scripts should support LF endings only
+ https://bugs.webkit.org/show_bug.cgi?id=79509
+
+ Reviewed by David Kilzer.
+
+ * gyp/generate-derived-sources.sh: Added property svn:eol-style.
+ * gyp/run-if-exists.sh: Added property svn:eol-style.
+ * gyp/update-info-plist.sh: Added property svn:eol-style.
+
+2012-03-09 Jessie Berlin <jberlin@apple.com>
+
+ Windows debug build fix.
+
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::shouldBlind):
+ Fix unreachable code warnings (which we treat as errors).
+
+2012-03-09 Thouraya ANDOLSI <thouraya.andolsi@st.com>
+
+ Reviewed by Zoltan Herczeg.
+
+ [Qt] Fix the SH4 build after r109834
+ https://bugs.webkit.org/show_bug.cgi?id=80492
+
+ * assembler/MacroAssemblerSH4.h:
+ (JSC::MacroAssemblerSH4::branchAdd32):
+ (JSC::MacroAssemblerSH4::branchSub32):
+
+2012-03-09 Andy Wingo <wingo@igalia.com>
+
+ Refactor code feature analysis in the parser
+ https://bugs.webkit.org/show_bug.cgi?id=79112
+
+ Reviewed by Geoffrey Garen.
+
+ This commit refactors the parser to more uniformly propagate flag
+ bits down and up the parse process, as the parser descends and
+ returns into nested blocks. Some flags get passed town to
+ subscopes, some apply to specific scopes only, and some get
+ unioned up after parsing subscopes.
+
+ The goal is to eventually be very precise with scoping
+ information, once we have block scopes: one block scope might use
+ `eval', which would require the emission of a symbol table within
+ that block and containing blocks, whereas another block in the
+ same function might not, allowing us to not emit a symbol table.
+
+ * parser/Nodes.h:
+ (JSC::ScopeFlags): Rename from CodeFeatures.
+ (JSC::ScopeNode::addScopeFlags):
+ (JSC::ScopeNode::scopeFlags): New accessors for m_scopeFlags.
+ (JSC::ScopeNode::isStrictMode):
+ (JSC::ScopeNode::usesEval):
+ (JSC::ScopeNode::usesArguments):
+ (JSC::ScopeNode::setUsesArguments):
+ (JSC::ScopeNode::usesThis):
+ (JSC::ScopeNode::needsActivationForMoreThanVariables):
+ (JSC::ScopeNode::needsActivation): Refactor these accessors to
+ operate on the m_scopeFlags member.
+ (JSC::ScopeNode::source):
+ (JSC::ScopeNode::sourceURL):
+ (JSC::ScopeNode::sourceID): Shuffle these definitions around; no
+ semantic change.
+ (JSC::ScopeNode::ScopeNode)
+ (JSC::ProgramNode::ProgramNode)
+ (JSC::EvalNode::EvalNode)
+ (JSC::FunctionBodyNode::FunctionBodyNode): Have these constructors
+ take a ScopeFlags as an argument, instead of a bool inStrictContext.
+
+ * parser/Nodes.cpp:
+ (JSC::ScopeNode::ScopeNode):
+ (JSC::ProgramNode::ProgramNode):
+ (JSC::ProgramNode::create):
+ (JSC::EvalNode::EvalNode):
+ (JSC::EvalNode::create):
+ (JSC::FunctionBodyNode::FunctionBodyNode):
+ (JSC::FunctionBodyNode::create): Adapt constructors to change.
+
+ * parser/ASTBuilder.h:
+ (JSC::ASTBuilder::ASTBuilder):
+ (JSC::ASTBuilder::thisExpr):
+ (JSC::ASTBuilder::createResolve):
+ (JSC::ASTBuilder::createFunctionBody):
+ (JSC::ASTBuilder::createFuncDeclStatement):
+ (JSC::ASTBuilder::createTryStatement):
+ (JSC::ASTBuilder::createWithStatement):
+ (JSC::ASTBuilder::addVar):
+ (JSC::ASTBuilder::Scope::Scope):
+ (Scope):
+ (ASTBuilder):
+ (JSC::ASTBuilder::makeFunctionCallNode): Don't track scope
+ features here. Instead rely on the base Parser mechanism to track
+ features.
+
+ * parser/NodeInfo.h (NodeInfo, NodeDeclarationInfo): "ScopeFlags".
+
+ * parser/Parser.h:
+ (JSC::Scope::Scope): Manage scope through flags, not
+ bit-booleans. This lets us uniformly propagate them up and down.
+ (JSC::Scope::declareWrite):
+ (JSC::Scope::declareParameter):
+ (JSC::Scope::useVariable):
+ (JSC::Scope::collectFreeVariables):
+ (JSC::Scope::getCapturedVariables):
+ (JSC::Scope::saveFunctionInfo):
+ (JSC::Scope::restoreFunctionInfo):
+ (JSC::Parser::pushScope): Adapt to use scope flags and their
+ accessors instead of bit-booleans.
+ * parser/Parser.cpp:
+ (JSC::::Parser):
+ (JSC::::parseInner):
+ (JSC::::didFinishParsing):
+ (JSC::::parseSourceElements):
+ (JSC::::parseVarDeclarationList):
+ (JSC::::parseConstDeclarationList):
+ (JSC::::parseWithStatement):
+ (JSC::::parseTryStatement):
+ (JSC::::parseFunctionBody):
+ (JSC::::parseFunctionInfo):
+ (JSC::::parseFunctionDeclaration):
+ (JSC::::parsePrimaryExpression): Hoist some of the flag handling
+ out of the "context" (ASTBuilder or SyntaxChecker) and to here.
+ Does not seem to have a performance impact.
+
+ * parser/SourceProviderCacheItem.h (SourceProviderCacheItem):
+ Cache the scopeflags.
+ * parser/SyntaxChecker.h: Remove evalCount() decl.
+
+ * runtime/Executable.cpp:
+ (JSC::EvalExecutable::compileInternal):
+ (JSC::ProgramExecutable::compileInternal):
+ (JSC::FunctionExecutable::produceCodeBlockFor):
+ * runtime/Executable.h:
+ (JSC::ScriptExecutable::ScriptExecutable):
+ (JSC::ScriptExecutable::usesEval):
+ (JSC::ScriptExecutable::usesArguments):
+ (JSC::ScriptExecutable::needsActivation):
+ (JSC::ScriptExecutable::isStrictMode):
+ (JSC::ScriptExecutable::recordParse):
+ (ScriptExecutable): ScopeFlags, not features.
+
+2012-03-08 Benjamin Poulain <bpoulain@apple.com>
+
+ Build fix for MSVC after r110266
+
+ Unreviewed. A #ifdef for MSVC was left over in r110266.
+
+ * runtime/RegExpObject.h:
+ (RegExpObject):
+
+2012-03-08 Benjamin Poulain <bpoulain@apple.com>
+
+ Allocate the RegExpObject's data with the Cell
+ https://bugs.webkit.org/show_bug.cgi?id=80654
+
+ Reviewed by Gavin Barraclough.
+
+ This patch removes the creation of RegExpObject's data to avoid the overhead
+ create by the allocation and destruction.
+
+ We RegExp are created repeatedly, this provides some performance improvment.
+ The PeaceKeeper test stringDetectBrowser improves by 10%.
+
+ * runtime/RegExpObject.cpp:
+ (JSC::RegExpObject::RegExpObject):
+ (JSC::RegExpObject::visitChildren):
+ (JSC::RegExpObject::getOwnPropertyDescriptor):
+ (JSC::RegExpObject::defineOwnProperty):
+ (JSC::RegExpObject::match):
+ * runtime/RegExpObject.h:
+ (JSC::RegExpObject::setRegExp):
+ (JSC::RegExpObject::regExp):
+ (JSC::RegExpObject::setLastIndex):
+ (JSC::RegExpObject::getLastIndex):
+ (RegExpObject):
+
+2012-03-08 Steve Falkenburg <sfalken@apple.com>
+
+ Separate WTF parts of JavaScriptCoreGenerated into WTFGenerated for Windows build
+ https://bugs.webkit.org/show_bug.cgi?id=80657
+
+ Preparation for WTF separation from JavaScriptCore.
+ The "Generated" vcproj files on Windows are necessary so Visual Studio can calculate correct
+ dependencies for generated files.
+
+ This also removes the PGO build targets from the WTF code, since we can't build instrumentation/optimization
+ versions of the WTF code independent of the JavaScriptCore code.
+
+ Reviewed by Jessie Berlin.
+
+ * JavaScriptCore.vcproj/JavaScriptCore.sln: Add WTFGenerated, update dependent projects.
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make: Removed WTF specific parts.
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.vcproj: Removed WTF specific parts.
+ * JavaScriptCore.vcproj/JavaScriptCore/build-generated-files.sh: Removed WTF specific parts.
+ * JavaScriptCore.vcproj/JavaScriptCore/copy-files.cmd: Removed WTF specific parts.
+ * JavaScriptCore.vcproj/JavaScriptCore/work-around-vs-dependency-tracking-bugs.py: Removed.
+ * JavaScriptCore.vcproj/JavaScriptCoreSubmit.sln: Add WTFGenerated, update dependent projects.
+ * JavaScriptCore.vcproj/WTF/WTF.vcproj: Remove PGO targets from WTF.
+ * JavaScriptCore.vcproj/WTF/WTFGenerated.make: Copied from Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make.
+ * JavaScriptCore.vcproj/WTF/WTFGenerated.vcproj: Copied from Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.vcproj.
+ * JavaScriptCore.vcproj/WTF/WTFGeneratedCommon.vsprops: Copied from Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedCommon.vsprops.
+ * JavaScriptCore.vcproj/WTF/WTFGeneratedDebug.vsprops: Copied from Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedDebug.vsprops.
+ * JavaScriptCore.vcproj/WTF/WTFGeneratedDebugAll.vsprops: Copied from Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedDebugAll.vsprops.
+ * JavaScriptCore.vcproj/WTF/WTFGeneratedDebugCairoCFLite.vsprops: Copied from Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedDebugCairoCFLite.vsprops.
+ * JavaScriptCore.vcproj/WTF/WTFGeneratedProduction.vsprops: Copied from Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedProduction.vsprops.
+ * JavaScriptCore.vcproj/WTF/WTFGeneratedRelease.vsprops: Copied from Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedRelease.vsprops.
+ * JavaScriptCore.vcproj/WTF/WTFGeneratedReleaseCairoCFLite.vsprops: Copied from Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedReleaseCairoCFLite.vsprops.
+ * JavaScriptCore.vcproj/WTF/WTFReleasePGO.vsprops: Removed.
+ * JavaScriptCore.vcproj/WTF/build-generated-files.sh: Copied from Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/build-generated-files.sh.
+ * JavaScriptCore.vcproj/WTF/copy-files.cmd: Copied from Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/copy-files.cmd.
+ * JavaScriptCore.vcproj/WTF/work-around-vs-dependency-tracking-bugs.py: Copied from Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/work-around-vs-dependency-tracking-bugs.py.
+
+2012-03-08 Benjamin Poulain <benjamin@webkit.org>
+
+ Fix the build of WebKit with WTFURL following the removal of ForwardingHeaders/wtf
+ https://bugs.webkit.org/show_bug.cgi?id=80652
+
+ Reviewed by Eric Seidel.
+
+ Fix the header, URLSegments.h is not part of the API.
+
+ * wtf/url/api/ParsedURL.h:
+
+2012-03-08 Ryosuke Niwa <rniwa@webkit.org>
+
+ Mac build fix for micro data API.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2012-03-08 Gavin Barraclough <barraclough@apple.com>
+
+ String.prototype.match and replace do not clear global regexp lastIndex per ES5.1 15.5.4.10
+ https://bugs.webkit.org/show_bug.cgi?id=26890
+
+ Reviewed by Oliver Hunt.
+
+ Per 15.10.6.2 step 9.a.1 called via the action of the last iteration of 15.5.4.10 8.f.i.
+
+ * runtime/StringPrototype.cpp:
+ (JSC::replaceUsingRegExpSearch):
+ (JSC::stringProtoFuncMatch):
+ - added calls to setLastIndex.
+
+2012-03-08 Matt Lilek <mrl@apple.com>
+
+ Don't enable VIDEO_TRACK on all OS X platforms
+ https://bugs.webkit.org/show_bug.cgi?id=80635
+
+ Reviewed by Eric Carlson.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2012-03-08 Oliver Hunt <oliver@apple.com>
+
+ Build fix. That day is not today.
+
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::shouldBlind):
+ * assembler/MacroAssemblerX86Common.h:
+ (MacroAssemblerX86Common):
+ (JSC::MacroAssemblerX86Common::shouldBlindForSpecificArch):
+
+2012-03-08 Oliver Hunt <oliver@apple.com>
+
+ Build fix. One of these days I'll manage to commit something that works everywhere.
+
+ * assembler/AbstractMacroAssembler.h:
+ (AbstractMacroAssembler):
+ * assembler/MacroAssemblerARMv7.h:
+ (MacroAssemblerARMv7):
+ * assembler/MacroAssemblerX86Common.h:
+ (JSC::MacroAssemblerX86Common::shouldBlindForSpecificArch):
+ (MacroAssemblerX86Common):
+
+2012-03-08 Chao-ying Fu <fu@mips.com>
+
+ Update MIPS patchOffsetGetByIdSlowCaseCall
+ https://bugs.webkit.org/show_bug.cgi?id=80302
+
+ Reviewed by Oliver Hunt.
+
+ * jit/JIT.h:
+ (JIT):
+
+2012-03-08 Oliver Hunt <oliver@apple.com>
+
+ Missing some places where we should be blinding 64bit values (and blinding something we shouldn't)
+ https://bugs.webkit.org/show_bug.cgi?id=80633
+
+ Reviewed by Gavin Barraclough.
+
+ Add 64-bit trap for shouldBlindForSpecificArch, so that we always blind
+ if there isn't a machine specific implementation (otherwise the 64bit value
+ got truncated and 32bit checks were used -- leaving 32bits untested).
+ Also add a bit of logic to ensure that we don't try to blind a few common
+ constants that go through the ImmPtr paths -- encoded numeric JSValues and
+ unencoded doubles with common "safe" values.
+
+ * assembler/AbstractMacroAssembler.h:
+ (JSC::AbstractMacroAssembler::shouldBlindForSpecificArch):
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::shouldBlindDouble):
+ (MacroAssembler):
+ (JSC::MacroAssembler::shouldBlind):
+ * assembler/MacroAssemblerX86Common.h:
+ (JSC::MacroAssemblerX86Common::shouldBlindForSpecificArch):
+
+2012-03-08 Mark Rowe <mrowe@apple.com>
+
+ <rdar://problem/11012572> Ensure that the staged frameworks path is in the search path for JavaScriptCore
+
+ Reviewed by Dan Bernstein.
+
+ * Configurations/Base.xcconfig:
+
+2012-03-08 Steve Falkenburg <sfalken@apple.com>
+
+ Fix line endings for copy-files.cmd.
+
+ If a cmd file doesn't have Windows line endings, it doesn't work properly.
+ In this case, the label :clean wasn't found, breaking the clean build.
+
+ Reviewed by Jessie Berlin.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/copy-files.cmd:
+
+2012-03-07 Filip Pizlo <fpizlo@apple.com>
+
+ DFG CFA incorrectly handles ValueToInt32
+ https://bugs.webkit.org/show_bug.cgi?id=80568
+
+ Reviewed by Gavin Barraclough.
+
+ Changed it match exactly the decision pattern used in
+ DFG::SpeculativeJIT::compileValueToInt32
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+
+2012-03-08 Viatcheslav Ostapenko <ostapenko.viatcheslav@nokia.com>
+
+ [Qt] [WK2] Webkit fails to link when compiled with force_static_libs_as_shared
+ https://bugs.webkit.org/show_bug.cgi?id=80524
+
+ Reviewed by Simon Hausmann.
+
+ Move IdentifierTable methods defintion to WTFThreadData.cpp to fix linking
+ of WTF library.
+
+ * runtime/Identifier.cpp:
+ * wtf/WTFThreadData.cpp:
+ (JSC):
+ (JSC::IdentifierTable::~IdentifierTable):
+ (JSC::IdentifierTable::add):
+
+2012-03-08 Filip Pizlo <fpizlo@apple.com>
+
+ DFG instruction count threshold should be lifted to 10000
+ https://bugs.webkit.org/show_bug.cgi?id=80579
+
+ Reviewed by Gavin Barraclough.
+
+ * runtime/Options.cpp:
+ (JSC::Options::initializeOptions):
+
+2012-03-07 Filip Pizlo <fpizlo@apple.com>
+
+ Incorrect tracking of abstract values of variables forced double
+ https://bugs.webkit.org/show_bug.cgi?id=80566
+ <rdar://problem/11001442>
+
+ Reviewed by Gavin Barraclough.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::mergeStateAtTail):
+
+2012-03-07 Chao-yng Fu <fu@mips.com>
+
+ [Qt] Fix the MIPS/SH4 build after r109834
+ https://bugs.webkit.org/show_bug.cgi?id=80492
+
+ Reviewed by Oliver Hunt.
+
+ Implement three-argument branch(Add,Sub)32.
+
+ * assembler/MacroAssemblerMIPS.h:
+ (JSC::MacroAssemblerMIPS::add32):
+ (MacroAssemblerMIPS):
+ (JSC::MacroAssemblerMIPS::sub32):
+ (JSC::MacroAssemblerMIPS::branchAdd32):
+ (JSC::MacroAssemblerMIPS::branchSub32):
+
+2012-03-07 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r110127.
+ http://trac.webkit.org/changeset/110127
+ https://bugs.webkit.org/show_bug.cgi?id=80562
+
+ compile failed on AppleWin (Requested by ukai on #webkit).
+
+ * heap/Heap.cpp:
+ (JSC::Heap::collectAllGarbage):
+ * heap/Heap.h:
+ (JSC):
+ (Heap):
+ * runtime/Executable.cpp:
+ (JSC::FunctionExecutable::FunctionExecutable):
+ (JSC::FunctionExecutable::finalize):
+ * runtime/Executable.h:
+ (FunctionExecutable):
+ (JSC::FunctionExecutable::create):
+ * runtime/JSGlobalData.cpp:
+ (WTF):
+ (Recompiler):
+ (WTF::Recompiler::operator()):
+ (JSC::JSGlobalData::recompileAllJSFunctions):
+ (JSC):
+ * runtime/JSGlobalData.h:
+ (JSGlobalData):
+ * runtime/JSGlobalObject.cpp:
+ (JSC::DynamicGlobalObjectScope::DynamicGlobalObjectScope):
+
+2012-03-07 Hojong Han <hojong.han@samsung.com>
+
+ The end atom of the marked block considered to filter invalid cells
+ https://bugs.webkit.org/show_bug.cgi?id=79191
+
+ Reviewed by Geoffrey Garen.
+
+ Register file could have stale pointers beyond the end atom of marked block.
+ Those pointers can weasel out of filtering in-middle-of-cell pointer.
+
+ * heap/MarkedBlock.h:
+ (JSC::MarkedBlock::isLiveCell):
+
+2012-03-07 Jessie Berlin <jberlin@apple.com>
+
+ Clean Windows build fails after r110033
+ https://bugs.webkit.org/show_bug.cgi?id=80553
+
+ Rubber-stamped by Jon Honeycutt and Eric Seidel.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/copy-files.cmd:
+ Place the implementation files next to their header files in the wtf/text subdirectory.
+ Use echo -F to tell xcopy that these are files (since there is apparently no flag).
+ * JavaScriptCore.vcproj/jsc/jsc.vcproj:
+ Update the path to those implementation files.
+ * JavaScriptCore.vcproj/testRegExp/testRegExp.vcproj:
+ Ditto.
+
+2012-03-07 Yuqiang Xian <yuqiang.xian@intel.com>
+
+ Eliminate redundant Phis in DFG
+ https://bugs.webkit.org/show_bug.cgi?id=80415
+
+ Reviewed by Filip Pizlo.
+
+ Although this may not have any advantage at current stage, this is towards
+ minimal SSA to make more high level optimizations (like bug 76770) easier.
+ We have the choices either to build minimal SSA from scratch or to
+ keep current simple Phi insertion mechanism and remove the redundancy
+ in another phase. Currently we choose the latter because the change
+ could be smaller.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * dfg/DFGDriver.cpp:
+ (JSC::DFG::compile):
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::Graph::dump):
+ * dfg/DFGRedundantPhiEliminationPhase.cpp: Added.
+ (DFG):
+ (RedundantPhiEliminationPhase):
+ (JSC::DFG::RedundantPhiEliminationPhase::RedundantPhiEliminationPhase):
+ (JSC::DFG::RedundantPhiEliminationPhase::run):
+ (JSC::DFG::RedundantPhiEliminationPhase::getRedundantReplacement):
+ (JSC::DFG::RedundantPhiEliminationPhase::replacePhiChild):
+ (JSC::DFG::RedundantPhiEliminationPhase::fixupPhis):
+ (JSC::DFG::RedundantPhiEliminationPhase::updateBlockVariableInformation):
+ (JSC::DFG::performRedundantPhiElimination):
+ * dfg/DFGRedundantPhiEliminationPhase.h: Added.
+ (DFG):
+
+2012-03-07 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Refactor recompileAllJSFunctions() to be less expensive
+ https://bugs.webkit.org/show_bug.cgi?id=80330
+
+ Reviewed by Geoffrey Garen.
+
+ This change is performance neutral on the JS benchmarks we track. It's mostly to improve page
+ load performance, which currently does at least a couple full GCs per navigation.
+
+ * heap/Heap.cpp:
+ (JSC::Heap::discardAllCompiledCode): Rename recompileAllJSFunctions to discardAllCompiledCode
+ because the function doesn't actually recompile anything (and never did); it simply throws code
+ away for it to be recompiled later if we determine we should do so.
+ (JSC):
+ (JSC::Heap::collectAllGarbage):
+ (JSC::Heap::addFunctionExecutable): Adds a newly created FunctionExecutable to the Heap's list.
+ (JSC::Heap::removeFunctionExecutable): Removes the specified FunctionExecutable from the Heap's list.
+ * heap/Heap.h:
+ (JSC):
+ (Heap):
+ * runtime/Executable.cpp: Added next and prev fields to FunctionExecutables so that they can
+ be used in DoublyLinkedLists.
+ (JSC::FunctionExecutable::FunctionExecutable):
+ (JSC::FunctionExecutable::finalize): Removes the FunctionExecutable from the Heap's list.
+ * runtime/Executable.h:
+ (FunctionExecutable):
+ (JSC::FunctionExecutable::create): Adds the FunctionExecutable to the Heap's list.
+ * runtime/JSGlobalData.cpp: Remove recompileAllJSFunctions, as it's the Heap's job to own and manage
+ the list of FunctionExecutables.
+ * runtime/JSGlobalData.h:
+ (JSGlobalData):
+ * runtime/JSGlobalObject.cpp:
+ (JSC::DynamicGlobalObjectScope::DynamicGlobalObjectScope): Use the new discardAllCompiledCode.
+
+2012-03-06 Oliver Hunt <oliver@apple.com>
+
+ Further harden 64-bit JIT
+ https://bugs.webkit.org/show_bug.cgi?id=80457
+
+ Reviewed by Filip Pizlo.
+
+ This patch implements blinding for ImmPtr. Rather than xor based blinding
+ we perform randomised pointer rotations in order to avoid the significant
+ cost in executable memory that would otherwise be necessary (and to avoid
+ the need for an additional scratch register in some cases).
+
+ As with the prior blinding patch there's a moderate amount of noise as we
+ correct the use of ImmPtr vs. TrustedImmPtr.
+
+ * assembler/AbstractMacroAssembler.h:
+ (ImmPtr):
+ (JSC::AbstractMacroAssembler::ImmPtr::asTrustedImmPtr):
+ * assembler/MacroAssembler.h:
+ (MacroAssembler):
+ (JSC::MacroAssembler::storePtr):
+ (JSC::MacroAssembler::branchPtr):
+ (JSC::MacroAssembler::shouldBlind):
+ (JSC::MacroAssembler::RotatedImmPtr::RotatedImmPtr):
+ (RotatedImmPtr):
+ (JSC::MacroAssembler::rotationBlindConstant):
+ (JSC::MacroAssembler::loadRotationBlindedConstant):
+ (JSC::MacroAssembler::convertInt32ToDouble):
+ (JSC::MacroAssembler::move):
+ (JSC::MacroAssembler::poke):
+ * assembler/MacroAssemblerARMv7.h:
+ (JSC::MacroAssemblerARMv7::storeDouble):
+ (JSC::MacroAssemblerARMv7::branchAdd32):
+ * assembler/MacroAssemblerX86_64.h:
+ (MacroAssemblerX86_64):
+ (JSC::MacroAssemblerX86_64::rotateRightPtr):
+ (JSC::MacroAssemblerX86_64::xorPtr):
+ * assembler/X86Assembler.h:
+ (X86Assembler):
+ (JSC::X86Assembler::xorq_rm):
+ (JSC::X86Assembler::rorq_i8r):
+ * dfg/DFGCCallHelpers.h:
+ (CCallHelpers):
+ (JSC::DFG::CCallHelpers::setupArgumentsWithExecState):
+ * dfg/DFGOSRExitCompiler32_64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+ * dfg/DFGOSRExitCompiler64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::createOSREntries):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::silentFillGPR):
+ (JSC::DFG::SpeculativeJIT::callOperation):
+ (JSC::DFG::SpeculativeJIT::emitEdgeCode):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::fillInteger):
+ (JSC::DFG::SpeculativeJIT::fillDouble):
+ (JSC::DFG::SpeculativeJIT::fillJSValue):
+ (JSC::DFG::SpeculativeJIT::emitCall):
+ (JSC::DFG::SpeculativeJIT::compileObjectEquality):
+ (JSC::DFG::SpeculativeJIT::compileLogicalNot):
+ (JSC::DFG::SpeculativeJIT::emitBranch):
+ * jit/JIT.cpp:
+ (JSC::JIT::emitOptimizationCheck):
+ * jit/JITArithmetic32_64.cpp:
+ (JSC::JIT::emitSlow_op_post_inc):
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitValueProfilingSite):
+ (JSC::JIT::emitGetVirtualRegister):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_mov):
+ (JSC::JIT::emit_op_new_object):
+ (JSC::JIT::emit_op_strcat):
+ (JSC::JIT::emit_op_ensure_property_exists):
+ (JSC::JIT::emit_op_resolve_skip):
+ (JSC::JIT::emitSlow_op_resolve_global):
+ (JSC::JIT::emit_op_resolve_with_base):
+ (JSC::JIT::emit_op_resolve_with_this):
+ (JSC::JIT::emit_op_jmp_scopes):
+ (JSC::JIT::emit_op_switch_imm):
+ (JSC::JIT::emit_op_switch_char):
+ (JSC::JIT::emit_op_switch_string):
+ (JSC::JIT::emit_op_throw_reference_error):
+ (JSC::JIT::emit_op_debug):
+ (JSC::JIT::emitSlow_op_resolve_global_dynamic):
+ (JSC::JIT::emit_op_new_array):
+ (JSC::JIT::emitSlow_op_new_array):
+ (JSC::JIT::emit_op_new_array_buffer):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emit_op_new_object):
+ (JSC::JIT::emit_op_strcat):
+ (JSC::JIT::emit_op_ensure_property_exists):
+ (JSC::JIT::emit_op_resolve_skip):
+ (JSC::JIT::emitSlow_op_resolve_global):
+ (JSC::JIT::emit_op_resolve_with_base):
+ (JSC::JIT::emit_op_resolve_with_this):
+ (JSC::JIT::emit_op_jmp_scopes):
+ (JSC::JIT::emit_op_switch_imm):
+ (JSC::JIT::emit_op_switch_char):
+ (JSC::JIT::emit_op_switch_string):
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC::JIT::emit_op_put_by_index):
+ * jit/JITStubCall.h:
+ (JITStubCall):
+ (JSC::JITStubCall::addArgument):
+
+2012-03-07 Simon Hausmann <simon.hausmann@nokia.com>
+
+ ARM build fix.
+
+ Reviewed by Zoltan Herczeg.
+
+ Implement three-argument branch(Add,Sub)32.
+
+ * assembler/MacroAssemblerARM.h:
+ (JSC::MacroAssemblerARM::add32):
+ (MacroAssemblerARM):
+ (JSC::MacroAssemblerARM::sub32):
+ (JSC::MacroAssemblerARM::branchAdd32):
+ (JSC::MacroAssemblerARM::branchSub32):
+
+2012-03-07 Andy Wingo <wingo@igalia.com>
+
+ Parser: Inline ScopeNodeData into ScopeNode
+ https://bugs.webkit.org/show_bug.cgi?id=79776
+
+ Reviewed by Geoffrey Garen.
+
+ It used to be that some ScopeNode members were kept in a separate
+ structure because sometimes they wouldn't be needed, and
+ allocating a ParserArena was expensive. This patch makes
+ ParserArena lazily allocate its IdentifierArena, allowing the
+ members to be included directly, which is simpler and easier to
+ reason about.
+
+ * parser/ParserArena.cpp:
+ (JSC::ParserArena::ParserArena):
+ (JSC::ParserArena::reset):
+ (JSC::ParserArena::isEmpty):
+ * parser/ParserArena.h:
+ (JSC::ParserArena::identifierArena): Lazily allocate the
+ IdentifierArena.
+
+ * parser/Nodes.cpp:
+ (JSC::ScopeNode::ScopeNode):
+ (JSC::ScopeNode::singleStatement):
+ (JSC::ProgramNode::create):
+ (JSC::EvalNode::create):
+ (JSC::FunctionBodyNode::create):
+ * parser/Nodes.h:
+ (JSC::ScopeNode::destroyData):
+ (JSC::ScopeNode::needsActivationForMoreThanVariables):
+ (JSC::ScopeNode::needsActivation):
+ (JSC::ScopeNode::hasCapturedVariables):
+ (JSC::ScopeNode::capturedVariableCount):
+ (JSC::ScopeNode::captures):
+ (JSC::ScopeNode::varStack):
+ (JSC::ScopeNode::functionStack):
+ (JSC::ScopeNode::neededConstants):
+ (ScopeNode):
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::ScopeNode::emitStatementsBytecode): Inline ScopeNodeData
+ into ScopeNode. Adapt accessors.
+
+2012-03-06 Eric Seidel <eric@webkit.org>
+
+ Make WTF public headers use fully-qualified include paths and remove ForwardingHeaders/wtf
+ https://bugs.webkit.org/show_bug.cgi?id=80363
+
+ Reviewed by Mark Rowe.
+
+ Historically WTF has been part of JavaScriptCore, and on Mac and Windows
+ its headers have appeared as part of the "private" headers exported by
+ JavaScriptCore. All of the WTF headers there are "flattened" into a single
+ private headers directory, and WebCore, WebKit and WebKit2 have used "ForwardingHeaders"
+ to re-map fully-qualified <wtf/text/Foo.h> includes to simple <JavaScriptCore/Foo.h> includes.
+
+ However, very soon, we are moving the WTF source code out of JavaScriptCore into its
+ own directory and project. As part of such, the WTF headers will no longer be part of
+ the JavaScriptCore private interfaces.
+ In preparation for that, this change makes both the Mac and Win builds export
+ WTF headers in a non-flattened manner. On Mac, that means into usr/local/include/wtf
+ (and subdirectories), on Windows for now that means JavaScriptCore/wtf (and subdirectories).
+
+ There are 5 parts to this change.
+ 1. Updates the JavaScriptCore XCode and VCProj files to actually install these headers
+ (and header directories) into the appropriate places in the build directory.
+ 2. Updates JavaScriptCore.xcodeproj to look for these WTF headers in this install location
+ (WebCore, WebKit, etc. had already been taught to look in previous patches).
+ 3. Fixes all JavaScriptCore source files, and WTF headers to include WTF headers
+ using fully qualified paths.
+ 4. Stops the Mac and Win builds from installing these WTF headers in their old "flattened" location.
+ 5. Removes WebCore and WebKit ForwardingHeaders/wtf directories now that the flattened headers no longer exist.
+
+ Unfortunately we see no way to do this change in smaller parts, since all of these steps are interdependant.
+ It is possible there are internal Apple projects which depend on JavaScriptCore/Foo.h working for WTF
+ headers, those will have to be updated to use <wtf/Foo.h> after this change.
+ I've discussed this proposed change at length with Mark Rowe, and my understanding is they
+ are ready for (and interested in) this change happening.
+
+ * API/tests/JSNode.c:
+ * API/tests/JSNodeList.c:
+ * Configurations/Base.xcconfig:
+ * JavaScriptCore.vcproj/JavaScriptCore/copy-files.cmd:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * assembler/MacroAssemblerCodeRef.h:
+ * bytecompiler/BytecodeGenerator.h:
+ * dfg/DFGOperations.cpp:
+ * heap/GCAssertions.h:
+ * heap/HandleHeap.h:
+ * heap/HandleStack.h:
+ * heap/MarkedSpace.h:
+ * heap/PassWeak.h:
+ * heap/Strong.h:
+ * heap/Weak.h:
+ * jit/HostCallReturnValue.cpp:
+ * jit/JIT.cpp:
+ * jit/JITStubs.cpp:
+ * jit/ThunkGenerators.cpp:
+ * parser/Lexer.cpp:
+ * runtime/Completion.cpp:
+ * runtime/Executable.cpp:
+ * runtime/Identifier.h:
+ * runtime/InitializeThreading.cpp:
+ * runtime/JSDateMath.cpp:
+ * runtime/JSGlobalObjectFunctions.cpp:
+ * runtime/JSStringBuilder.h:
+ * runtime/JSVariableObject.h:
+ * runtime/NumberPrototype.cpp:
+ * runtime/WriteBarrier.h:
+ * tools/CodeProfile.cpp:
+ * tools/TieredMMapArray.h:
+ * wtf/AVLTree.h:
+ * wtf/Alignment.h:
+ * wtf/AlwaysInline.h:
+ * wtf/ArrayBufferView.h:
+ * wtf/Assertions.h:
+ * wtf/Atomics.h:
+ * wtf/Bitmap.h:
+ * wtf/BoundsCheckedPointer.h:
+ * wtf/CheckedArithmetic.h:
+ * wtf/Deque.h:
+ * wtf/ExportMacros.h:
+ * wtf/FastAllocBase.h:
+ * wtf/FastMalloc.h:
+ * wtf/Float32Array.h:
+ * wtf/Float64Array.h:
+ * wtf/Functional.h:
+ * wtf/HashCountedSet.h:
+ * wtf/HashFunctions.h:
+ * wtf/HashMap.h:
+ * wtf/HashSet.h:
+ * wtf/HashTable.h:
+ * wtf/HashTraits.h:
+ * wtf/Int16Array.h:
+ * wtf/Int32Array.h:
+ * wtf/Int8Array.h:
+ * wtf/IntegralTypedArrayBase.h:
+ * wtf/ListHashSet.h:
+ * wtf/MainThread.h:
+ * wtf/MetaAllocator.h:
+ * wtf/Noncopyable.h:
+ * wtf/OwnArrayPtr.h:
+ * wtf/OwnPtr.h:
+ * wtf/PackedIntVector.h:
+ * wtf/ParallelJobs.h:
+ * wtf/PassOwnArrayPtr.h:
+ * wtf/PassOwnPtr.h:
+ * wtf/PassRefPtr.h:
+ * wtf/PassTraits.h:
+ * wtf/Platform.h:
+ * wtf/PossiblyNull.h:
+ * wtf/RefCounted.h:
+ * wtf/RefCountedLeakCounter.h:
+ * wtf/RefPtr.h:
+ * wtf/RetainPtr.h:
+ * wtf/SimpleStats.h:
+ * wtf/Spectrum.h:
+ * wtf/StdLibExtras.h:
+ * wtf/TCPageMap.h:
+ * wtf/TemporaryChange.h:
+ * wtf/ThreadSafeRefCounted.h:
+ * wtf/Threading.h:
+ * wtf/ThreadingPrimitives.h:
+ * wtf/TypeTraits.h:
+ * wtf/TypedArrayBase.h:
+ * wtf/Uint16Array.h:
+ * wtf/Uint32Array.h:
+ * wtf/Uint8Array.h:
+ * wtf/Uint8ClampedArray.h:
+ * wtf/UnusedParam.h:
+ * wtf/Vector.h:
+ * wtf/VectorTraits.h:
+ * wtf/dtoa/double-conversion.h:
+ * wtf/dtoa/utils.h:
+ * wtf/gobject/GRefPtr.h:
+ * wtf/gobject/GlibUtilities.h:
+ * wtf/text/AtomicString.h:
+ * wtf/text/AtomicStringImpl.h:
+ * wtf/text/CString.h:
+ * wtf/text/StringConcatenate.h:
+ * wtf/text/StringHash.h:
+ * wtf/text/WTFString.h:
+ * wtf/unicode/CharacterNames.h:
+ * wtf/unicode/UTF8.h:
+ * wtf/unicode/glib/UnicodeGLib.h:
+ * wtf/unicode/qt4/UnicodeQt4.h:
+ * wtf/unicode/wince/UnicodeWinCE.h:
+ * wtf/url/api/ParsedURL.h:
+ * wtf/url/api/URLString.h:
+ * wtf/wince/FastMallocWinCE.h:
+ * yarr/YarrJIT.cpp:
+
+2012-03-06 Gavin Barraclough <barraclough@apple.com>
+
+ Array.prototype functions should throw if delete fails
+ https://bugs.webkit.org/show_bug.cgi?id=80467
+
+ Reviewed by Oliver Hunt.
+
+ All calls to [[Delete]] from Array.prototype are specified to pass 'true' as the value of Throw.
+ In the case of shift/unshift, these are also missing a throw from the 'put' in the implementations
+ in JSArray.cpp. There are effectively three copies of each of the generic shift/unshift routines,
+ one in splice, one in ArrayPrototype's shift/unshift methods, and one in JSArray's shift/unshift
+ routines, for handling arrays with holes. These three copies should be unified.
+
+ * runtime/ArrayPrototype.cpp:
+ (JSC::shift):
+ (JSC::unshift):
+ - Added - shared copies of the shift/unshift functionality.
+ (JSC::arrayProtoFuncPop):
+ - should throw if the delete fails.
+ (JSC::arrayProtoFuncReverse):
+ - should throw if the delete fails.
+ (JSC::arrayProtoFuncShift):
+ (JSC::arrayProtoFuncSplice):
+ (JSC::arrayProtoFuncUnShift):
+ - use shift/unshift.
+ * runtime/JSArray.cpp:
+ (JSC::JSArray::shiftCount):
+ (JSC::JSArray::unshiftCount):
+ - Don't try to handle arrays with holes; return a value indicating
+ the generic routine should be used instead.
+ * runtime/JSArray.h:
+ - declaration for shiftCount/unshiftCount changed.
+ * tests/mozilla/js1_6/Array/regress-304828.js:
+ - this was asserting incorrect behaviour.
+
+2012-03-06 Raphael Kubo da Costa <kubo@profusion.mobi>
+
+ [CMake] Make the removal of transitive library dependencies work with CMake < 2.8.7.
+ https://bugs.webkit.org/show_bug.cgi?id=80469
+
+ Reviewed by Antonio Gomes.
+
+ * CMakeLists.txt: Manually set the LINK_INTERFACE_LIBRARIES target
+ property on the library being created.
+
+2012-03-06 Yuqiang Xian <yuqiang.xian@intel.com>
+
+ DFG BasicBlock should group the Phi nodes together and separate them
+ from the other nodes
+ https://bugs.webkit.org/show_bug.cgi?id=80361
+
+ Reviewed by Filip Pizlo.
+
+ This would make it more efficient to remove the redundant Phi nodes or
+ insert new Phi nodes for SSA, besides providing a cleaner BasicBlock structure.
+ This is performance neutral on SunSpider, V8 and Kraken.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::clobberStructures):
+ (JSC::DFG::AbstractState::dump):
+ * dfg/DFGBasicBlock.h:
+ (JSC::DFG::BasicBlock::BasicBlock):
+ (BasicBlock):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::addToGraph):
+ (JSC::DFG::ByteCodeParser::insertPhiNode):
+ * dfg/DFGCFAPhase.cpp:
+ (JSC::DFG::CFAPhase::performBlockCFA):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::pureCSE):
+ (JSC::DFG::CSEPhase::impureCSE):
+ (JSC::DFG::CSEPhase::globalVarLoadElimination):
+ (JSC::DFG::CSEPhase::getByValLoadElimination):
+ (JSC::DFG::CSEPhase::checkFunctionElimination):
+ (JSC::DFG::CSEPhase::checkStructureLoadElimination):
+ (JSC::DFG::CSEPhase::getByOffsetLoadElimination):
+ (JSC::DFG::CSEPhase::getPropertyStorageLoadElimination):
+ (JSC::DFG::CSEPhase::getIndexedPropertyStorageLoadElimination):
+ (JSC::DFG::CSEPhase::getScopeChainLoadElimination):
+ (JSC::DFG::CSEPhase::performBlockCSE):
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::Graph::dump):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2012-03-06 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ GCActivityCallback timer should vary with the length of the previous GC
+ https://bugs.webkit.org/show_bug.cgi?id=80344
+
+ Reviewed by Geoffrey Garen.
+
+ * heap/Heap.cpp: Gave Heap the ability to keep track of the length of its last
+ GC length so that the GC Activity Callback can use it.
+ (JSC::Heap::Heap):
+ (JSC::Heap::collect):
+ * heap/Heap.h:
+ (JSC::Heap::lastGCLength):
+ (Heap):
+ * runtime/GCActivityCallbackCF.cpp:
+ (JSC):
+ (JSC::DefaultGCActivityCallback::operator()): Use the length of the Heap's last
+ GC to determine the length of our timer trigger (currently set at 100x the duration
+ of the last GC).
+
+2012-03-06 Rob Buis <rbuis@rim.com>
+
+ BlackBerry] Fix cast-align gcc warnings when compiling JSC
+ https://bugs.webkit.org/show_bug.cgi?id=80420
+
+ Reviewed by Gavin Barraclough.
+
+ Fix warnings given in Blackberry build.
+
+ * heap/CopiedBlock.h:
+ (JSC::CopiedBlock::CopiedBlock):
+ * wtf/RefCountedArray.h:
+ (WTF::RefCountedArray::Header::fromPayload):
+
+2012-03-06 Gavin Barraclough <barraclough@apple.com>
+
+ writable/configurable not respected for some properties of Function/String/Arguments
+ https://bugs.webkit.org/show_bug.cgi?id=80436
+
+ Reviewed by Oliver Hunt.
+
+ Special properties should behave like regular properties.
+
+ * runtime/Arguments.cpp:
+ (JSC::Arguments::defineOwnProperty):
+ - Mis-nested logic for making read-only properties non-live.
+ * runtime/JSFunction.cpp:
+ (JSC::JSFunction::put):
+ - arguments/length/caller are non-writable, non-configurable - reject appropriately.
+ (JSC::JSFunction::deleteProperty):
+ - Attempting to delete prototype/caller should fail.
+ (JSC::JSFunction::defineOwnProperty):
+ - Ensure prototype is reified on attempt to reify it.
+ - arguments/length/caller are non-writable, non-configurable - reject appropriately.
+ * runtime/JSFunction.h:
+ - added declaration for defineOwnProperty.
+ (JSFunction):
+ * runtime/StringObject.cpp:
+ (JSC::StringObject::put):
+ - length is non-writable, non-configurable - reject appropriately.
+
+2012-03-06 Ulan Degenbaev <ulan@chromium.org>
+
+ TypedArray subarray call for subarray does not clamp the end index parameter properly
+ https://bugs.webkit.org/show_bug.cgi?id=80285
+
+ Reviewed by Kenneth Russell.
+
+ * wtf/ArrayBufferView.h:
+ (WTF::ArrayBufferView::calculateOffsetAndLength):
+
+2012-03-06 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r109837.
+ http://trac.webkit.org/changeset/109837
+ https://bugs.webkit.org/show_bug.cgi?id=80399
+
+ breaks Mac Productions builds, too late to try and fix it
+ tonight (Requested by eseidel on #webkit).
+
+ * API/tests/JSNode.c:
+ * API/tests/JSNodeList.c:
+ * Configurations/Base.xcconfig:
+ * JavaScriptCore.vcproj/JavaScriptCore/copy-files.cmd:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * assembler/MacroAssemblerCodeRef.h:
+ * bytecompiler/BytecodeGenerator.h:
+ * dfg/DFGOperations.cpp:
+ * heap/GCAssertions.h:
+ * heap/HandleHeap.h:
+ * heap/HandleStack.h:
+ * heap/MarkedSpace.h:
+ * heap/PassWeak.h:
+ * heap/Strong.h:
+ * heap/Weak.h:
+ * jit/HostCallReturnValue.cpp:
+ * jit/JIT.cpp:
+ * jit/JITStubs.cpp:
+ * jit/ThunkGenerators.cpp:
+ * parser/Lexer.cpp:
+ * runtime/Completion.cpp:
+ * runtime/Executable.cpp:
+ * runtime/Identifier.h:
+ * runtime/InitializeThreading.cpp:
+ * runtime/JSDateMath.cpp:
+ * runtime/JSGlobalObjectFunctions.cpp:
+ * runtime/JSStringBuilder.h:
+ * runtime/JSVariableObject.h:
+ * runtime/NumberPrototype.cpp:
+ * runtime/WriteBarrier.h:
+ * tools/CodeProfile.cpp:
+ * tools/TieredMMapArray.h:
+ * yarr/YarrJIT.cpp:
+
+2012-03-06 Zoltan Herczeg <zherczeg@webkit.org>
+
+ [Qt][ARM] Speculative buildfix after r109834.
+
+ Reviewed by Csaba Osztrogonác.
+
+ * assembler/MacroAssemblerARM.h:
+ (JSC::MacroAssemblerARM::and32):
+ (MacroAssemblerARM):
+
+2012-03-05 Gavin Barraclough <barraclough@apple.com>
+
+ Unreviewed windows build fix pt 2.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2012-03-05 Gavin Barraclough <barraclough@apple.com>
+
+ Unreviewed windows build fix pt 1.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2012-03-05 Gavin Barraclough <barraclough@apple.com>
+
+ putByIndex should throw in strict mode
+ https://bugs.webkit.org/show_bug.cgi?id=80335
+
+ Reviewed by Filip Pizlo.
+
+ Make the MethodTable PutByIndex trap take a boolean 'shouldThrow' parameter.
+
+ This is a largely mechanical change, simply adding an extra parameter to a number
+ of functions. Some call sites need perform additional exception checks, and
+ operationPutByValBeyondArrayBounds needs to know whether it is strict or not.
+
+ This patch doesn't fix a missing throw from some cases of shift/unshift (this is
+ an existing bug), I'll follow up with a third patch to handle that.
+
+ * API/JSObjectRef.cpp:
+ (JSObjectSetPropertyAtIndex):
+ * JSCTypedArrayStubs.h:
+ (JSC):
+ * dfg/DFGOperations.cpp:
+ (JSC::DFG::putByVal):
+ * dfg/DFGOperations.h:
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * jsc.cpp:
+ (GlobalObject::finishCreation):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ * runtime/Arguments.cpp:
+ (JSC::Arguments::putByIndex):
+ * runtime/Arguments.h:
+ (Arguments):
+ * runtime/ArrayPrototype.cpp:
+ (JSC::arrayProtoFuncPush):
+ (JSC::arrayProtoFuncReverse):
+ (JSC::arrayProtoFuncShift):
+ (JSC::arrayProtoFuncSort):
+ (JSC::arrayProtoFuncSplice):
+ (JSC::arrayProtoFuncUnShift):
+ * runtime/ClassInfo.h:
+ (MethodTable):
+ * runtime/JSArray.cpp:
+ (JSC::SparseArrayValueMap::put):
+ (JSC::JSArray::put):
+ (JSC::JSArray::putByIndex):
+ (JSC::JSArray::putByIndexBeyondVectorLength):
+ (JSC::JSArray::push):
+ (JSC::JSArray::shiftCount):
+ (JSC::JSArray::unshiftCount):
+ * runtime/JSArray.h:
+ (SparseArrayValueMap):
+ (JSArray):
+ * runtime/JSByteArray.cpp:
+ (JSC::JSByteArray::putByIndex):
+ * runtime/JSByteArray.h:
+ (JSByteArray):
+ * runtime/JSCell.cpp:
+ (JSC::JSCell::putByIndex):
+ * runtime/JSCell.h:
+ (JSCell):
+ * runtime/JSNotAnObject.cpp:
+ (JSC::JSNotAnObject::putByIndex):
+ * runtime/JSNotAnObject.h:
+ (JSNotAnObject):
+ * runtime/JSONObject.cpp:
+ (JSC::Walker::walk):
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::putByIndex):
+ * runtime/JSObject.h:
+ (JSC::JSValue::putByIndex):
+ * runtime/RegExpConstructor.cpp:
+ (JSC::RegExpMatchesArray::fillArrayInstance):
+ * runtime/RegExpMatchesArray.h:
+ (JSC::RegExpMatchesArray::putByIndex):
+ * runtime/StringPrototype.cpp:
+ (JSC::stringProtoFuncSplit):
+
+2012-03-05 Yuqiang Xian <yuqiang.xian@intel.com>
+
+ PredictNone is incorrectly treated as isDoublePrediction
+ https://bugs.webkit.org/show_bug.cgi?id=80365
+
+ Reviewed by Filip Pizlo.
+
+ Also it is incorrectly treated as isFixedIndexedStorageObjectPrediction.
+
+ * bytecode/PredictedType.h:
+ (JSC::isFixedIndexedStorageObjectPrediction):
+ (JSC::isDoublePrediction):
+
+2012-03-05 Filip Pizlo <fpizlo@apple.com>
+
+ The LLInt should work even when the JIT is disabled
+ https://bugs.webkit.org/show_bug.cgi?id=80340
+ <rdar://problem/10922235>
+
+ Reviewed by Gavin Barraclough.
+
+ * assembler/MacroAssemblerCodeRef.h:
+ (JSC::MacroAssemblerCodePtr::createLLIntCodePtr):
+ (MacroAssemblerCodeRef):
+ (JSC::MacroAssemblerCodeRef::createLLIntCodeRef):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::initialize):
+ (JSC::Interpreter::execute):
+ (JSC::Interpreter::executeCall):
+ (JSC::Interpreter::executeConstruct):
+ * jit/JIT.h:
+ (JSC::JIT::compileCTINativeCall):
+ * jit/JITStubs.h:
+ (JSC::JITThunks::ctiNativeCall):
+ (JSC::JITThunks::ctiNativeConstruct):
+ * llint/LLIntEntrypoints.cpp:
+ (JSC::LLInt::getFunctionEntrypoint):
+ (JSC::LLInt::getEvalEntrypoint):
+ (JSC::LLInt::getProgramEntrypoint):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ (LLInt):
+ * llint/LLIntSlowPaths.h:
+ (LLInt):
+ * llint/LowLevelInterpreter.h:
+ * llint/LowLevelInterpreter32_64.asm:
+ * runtime/Executable.h:
+ (NativeExecutable):
+ (JSC::NativeExecutable::create):
+ (JSC::NativeExecutable::finishCreation):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ * runtime/JSGlobalData.h:
+ (JSGlobalData):
+ * runtime/Options.cpp:
+ (Options):
+ (JSC::Options::parse):
+ (JSC::Options::initializeOptions):
+ * runtime/Options.h:
+ (Options):
+ * wtf/Platform.h:
+
+2012-03-05 Yuqiang Xian <yuqiang.xian@intel.com>
+
+ Checks for dead variables are not sufficient when fixing the expected
+ values in DFG OSR entry
+ https://bugs.webkit.org/show_bug.cgi?id=80371
+
+ Reviewed by Filip Pizlo.
+
+ A dead variable should be identified when there's no node referencing it.
+ But we currently failed to catch the case where there are some nodes
+ referencing a variable but those nodes are actually not referenced by
+ others so will be ignored in code generation. In such case we should
+ also consider that variable to be a dead variable in the block and fix
+ the expected values.
+ This is performance neutral on SunSpider, V8 and Kraken.
+
+ * dfg/DFGJITCompiler.h:
+ (JSC::DFG::JITCompiler::noticeOSREntry):
+
+2012-03-05 Oliver Hunt <oliver@apple.com>
+
+ Fix Qt build.
+
+ * assembler/AbstractMacroAssembler.h:
+ * assembler/MacroAssembler.h:
+ (MacroAssembler):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileArithSub):
+ * jit/JITArithmetic32_64.cpp:
+ (JSC::JIT::emitSub32Constant):
+
+2012-03-05 Eric Seidel <eric@webkit.org>
+
+ Update JavaScriptCore files to use fully-qualified WTF include paths
+ https://bugs.webkit.org/show_bug.cgi?id=79960
+
+ Reviewed by Adam Barth.
+
+ This change does 5 small/related things:
+ 1. Updates JavaScriptCore.xcodeproj to install WTF headers into $BUILD/usr/local/include
+ (WebCore, WebKit were already setup to look there, but JavaScriptCore.xcodeproj
+ was not installing headers there.)
+ 2. Makes JavaScriptCore targets include $BUILD/usr/local/include in their
+ header search path, as that's where the WTF headers will be installed.
+ 3. Similarly updates JavaScriptCore.vcproj/copy-files.cmd to copy WTF headers to PrivateHeaders/wtf/*
+ in addition to the current behavior of flattening all headers to PrivateHeaders/*.h.
+ 4. Updates a bunch of JSC files to use #include <wtf/Foo.h> instead of #include "Foo.h"
+ since soon the WTF headers will not be part of the JavaScriptCore Xcode project.
+ 5. Makes build-webkit build the WTF XCode project by default.
+
+ * API/tests/JSNode.c:
+ * API/tests/JSNodeList.c:
+ * Configurations/Base.xcconfig:
+ * assembler/MacroAssemblerCodeRef.h:
+ * bytecompiler/BytecodeGenerator.h:
+ * dfg/DFGOperations.cpp:
+ * heap/GCAssertions.h:
+ * heap/HandleHeap.h:
+ * heap/HandleStack.h:
+ * heap/MarkedSpace.h:
+ * heap/PassWeak.h:
+ * heap/Strong.h:
+ * heap/Weak.h:
+ * jit/HostCallReturnValue.cpp:
+ * jit/JIT.cpp:
+ * jit/JITStubs.cpp:
+ * jit/ThunkGenerators.cpp:
+ * parser/Lexer.cpp:
+ * runtime/Completion.cpp:
+ * runtime/Executable.cpp:
+ * runtime/Identifier.h:
+ * runtime/InitializeThreading.cpp:
+ * runtime/JSDateMath.cpp:
+ * runtime/JSGlobalObjectFunctions.cpp:
+ * runtime/JSStringBuilder.h:
+ * runtime/JSVariableObject.h:
+ * runtime/NumberPrototype.cpp:
+ * runtime/WriteBarrier.h:
+ * tools/CodeProfile.cpp:
+ * tools/TieredMMapArray.h:
+ * yarr/YarrJIT.cpp:
+
+2012-03-05 Oliver Hunt <oliver@apple.com>
+
+ Add basic support for constant blinding to the JIT
+ https://bugs.webkit.org/show_bug.cgi?id=80354
+
+ Reviewed by Filip Pizlo.
+
+ This patch adds basic constant blinding support to the JIT, at the
+ MacroAssembler level. This means all JITs in JSC (Yarr, baseline, and DFG)
+ get constant blinding. Woo!
+
+ This patch only introduces blinding for Imm32, a later patch will do similar
+ for ImmPtr. In order to make misuse of Imm32 as a trusted type essentially
+ impossible, we make TrustedImm32 a private parent of Imm32 and add an explicit
+ accessor that's needed to access the actual value. This also means you cannot
+ accidentally pass an untrusted value to a function that does not perform
+ blinding.
+
+ To make everything work sensibly, this patch also corrects some code that was using
+ Imm32 when TrustedImm32 could be used, and refactors a few callers that use
+ untrusted immediates, so that they call slightly different varaints of the functions
+ that they used previously. This is largely necessary to deal with x86-32 not having
+ sufficient registers to handle the additional work required when we choose to blind
+ a constant.
+
+ * assembler/AbstractMacroAssembler.h:
+ (JSC::AbstractMacroAssembler::Imm32::asTrustedImm32):
+ (Imm32):
+ (JSC::AbstractMacroAssembler::beginUninterruptedSequence):
+ (JSC::AbstractMacroAssembler::endUninterruptedSequence):
+ (JSC::AbstractMacroAssembler::AbstractMacroAssembler):
+ (AbstractMacroAssembler):
+ (JSC::AbstractMacroAssembler::inUninterruptedSequence):
+ (JSC::AbstractMacroAssembler::random):
+ (JSC::AbstractMacroAssembler::scratchRegisterForBlinding):
+ (JSC::AbstractMacroAssembler::shouldBlindForSpecificArch):
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::addressForPoke):
+ (MacroAssembler):
+ (JSC::MacroAssembler::poke):
+ (JSC::MacroAssembler::branchPtr):
+ (JSC::MacroAssembler::branch32):
+ (JSC::MacroAssembler::convertInt32ToDouble):
+ (JSC::MacroAssembler::shouldBlind):
+ (JSC::MacroAssembler::BlindedImm32::BlindedImm32):
+ (BlindedImm32):
+ (JSC::MacroAssembler::keyForConstant):
+ (JSC::MacroAssembler::xorBlindConstant):
+ (JSC::MacroAssembler::additionBlindedConstant):
+ (JSC::MacroAssembler::andBlindedConstant):
+ (JSC::MacroAssembler::orBlindedConstant):
+ (JSC::MacroAssembler::loadXorBlindedConstant):
+ (JSC::MacroAssembler::add32):
+ (JSC::MacroAssembler::addPtr):
+ (JSC::MacroAssembler::and32):
+ (JSC::MacroAssembler::andPtr):
+ (JSC::MacroAssembler::move):
+ (JSC::MacroAssembler::or32):
+ (JSC::MacroAssembler::store32):
+ (JSC::MacroAssembler::sub32):
+ (JSC::MacroAssembler::subPtr):
+ (JSC::MacroAssembler::xor32):
+ (JSC::MacroAssembler::branchAdd32):
+ (JSC::MacroAssembler::branchMul32):
+ (JSC::MacroAssembler::branchSub32):
+ (JSC::MacroAssembler::trustedImm32ForShift):
+ (JSC::MacroAssembler::lshift32):
+ (JSC::MacroAssembler::rshift32):
+ (JSC::MacroAssembler::urshift32):
+ * assembler/MacroAssemblerARMv7.h:
+ (MacroAssemblerARMv7):
+ (JSC::MacroAssemblerARMv7::scratchRegisterForBlinding):
+ (JSC::MacroAssemblerARMv7::shouldBlindForSpecificArch):
+ * assembler/MacroAssemblerX86_64.h:
+ (JSC::MacroAssemblerX86_64::branchSubPtr):
+ (MacroAssemblerX86_64):
+ (JSC::MacroAssemblerX86_64::scratchRegisterForBlinding):
+ * dfg/DFGJITCompiler.cpp:
+ (JSC::DFG::JITCompiler::linkOSRExits):
+ (JSC::DFG::JITCompiler::compileBody):
+ (JSC::DFG::JITCompiler::compileFunction):
+ * dfg/DFGOSRExitCompiler32_64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+ * dfg/DFGOSRExitCompiler64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ (JSC::DFG::SpeculativeJIT::compileArithSub):
+ (JSC::DFG::SpeculativeJIT::compileStrictEqForConstant):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::callOperation):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::emitCall):
+ (JSC::DFG::SpeculativeJIT::compileObjectEquality):
+ (JSC::DFG::SpeculativeJIT::compileDoubleCompare):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::emitCall):
+ (JSC::DFG::SpeculativeJIT::compileDoubleCompare):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileSlowCases):
+ (JSC::JIT::privateCompile):
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::compileBinaryArithOp):
+ (JSC::JIT::emit_op_add):
+ (JSC::JIT::emit_op_mul):
+ (JSC::JIT::emit_op_div):
+ * jit/JITArithmetic32_64.cpp:
+ (JSC::JIT::emitAdd32Constant):
+ (JSC::JIT::emitSub32Constant):
+ (JSC::JIT::emitBinaryDoubleOp):
+ (JSC::JIT::emitSlow_op_mul):
+ (JSC::JIT::emit_op_div):
+ * jit/JITCall.cpp:
+ (JSC::JIT::compileLoadVarargs):
+ * jit/JITCall32_64.cpp:
+ (JSC::JIT::compileLoadVarargs):
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::updateTopCallFrame):
+ (JSC::JIT::emitValueProfilingSite):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emitSlow_op_jfalse):
+ (JSC::JIT::emitSlow_op_jtrue):
+ * jit/JITStubCall.h:
+ (JITStubCall):
+ (JSC::JITStubCall::addArgument):
+ * yarr/YarrJIT.cpp:
+ (JSC::Yarr::YarrGenerator::backtrack):
+
+2012-03-05 Gavin Barraclough <barraclough@apple.com>
+
+ putByIndex should throw in strict mode
+ https://bugs.webkit.org/show_bug.cgi?id=80335
+
+ Reviewed by Filip Pizlo.
+
+ We'll need to pass an additional parameter.
+
+ Part 1 - rename JSValue::put() for integer indices to JSValue::putByIndex()
+ to match the method in the MethodTable, make this take a parameter indicating
+ whether the put should throw. This fixes the cases where the base of the put
+ is a primitive.
+
+ * dfg/DFGOperations.cpp:
+ (DFG):
+ (JSC::DFG::putByVal):
+ (JSC::DFG::operationPutByValInternal):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::execute):
+ (JSC::Interpreter::privateExecute):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ * runtime/JSObject.h:
+ (JSC::JSValue::putByIndex):
+ * runtime/JSValue.cpp:
+ (JSC):
+ * runtime/JSValue.h:
+ (JSValue):
+
+2012-03-05 Sam Weinig <sam@webkit.org>
+
+ Add support for hosting layers in the window server in WebKit2
+ <rdar://problem/10400246>
+ https://bugs.webkit.org/show_bug.cgi?id=80310
+
+ Reviewed by Anders Carlsson.
+
+ * wtf/Platform.h:
+ Add HAVE_LAYER_HOSTING_IN_WINDOW_SERVER.
+
+2012-03-05 Filip Pizlo <fpizlo@apple.com>
+
+ Unreviewed, attempted build fix for !ENABLE(JIT) after r109705.
+
+ * bytecode/ExecutionCounter.cpp:
+ (JSC::ExecutionCounter::applyMemoryUsageHeuristics):
+ * bytecode/ExecutionCounter.h:
+
+2012-03-05 Patrick Gansterer <paroga@webkit.org>
+
+ Unreviewed. Build fix for !ENABLE(JIT) after r109705.
+
+ * bytecode/ExecutionCounter.cpp:
+ * bytecode/ExecutionCounter.h:
+
+2012-03-05 Andy Wingo <wingo@igalia.com>
+
+ Lexer: Specialize character predicates for LChar, UChar
+ https://bugs.webkit.org/show_bug.cgi?id=79677
+
+ Reviewed by Oliver Hunt.
+
+ This patch specializes isIdentStart, isIdentPart, isWhiteSpace,
+ and isLineTerminator to perform a more limited number of checks if
+ the lexer is being instantiated to work on LChar sequences. This
+ is about a 1.5% win on the --parse-only suite, here.
+
+ * parser/Lexer.cpp:
+ (JSC::isLatin1): New static helper, specialized for LChar and
+ UChar.
+ (JSC::typesOfLatin1Characters): Rename from
+ typesOfASCIICharacters, and expand to the range of the LChar
+ type. All uses of isASCII are changed to use isLatin1. Generated
+ using libunistring.
+ (JSC::isNonLatin1IdentStart):
+ (JSC::isIdentStart):
+ (JSC::isNonLatin1IdentPart):
+ (JSC::isIdentPart):
+ (JSC::Lexer::shiftLineTerminator):
+ (JSC::Lexer::parseIdentifier):
+ (JSC::Lexer::parseIdentifierSlowCase):
+ (JSC::Lexer::parseStringSlowCase):
+ (JSC::Lexer::parseMultilineComment):
+ (JSC::Lexer::lex):
+ (JSC::Lexer::scanRegExp):
+ (JSC::Lexer::skipRegExp): Sprinkle static_cast<T>(_) around.
+ * parser/Lexer.h:
+ (JSC::Lexer::isWhiteSpace):
+ (JSC::Lexer::isLineTerminator):
+ * KeywordLookupGenerator.py:
+ (Trie.printAsC): Declare specialized isIdentPart static functions.
+
+2012-03-05 Carlos Garcia Campos <cgarcia@igalia.com>
+
+ Unreviewed. Fix make distcheck.
+
+ * GNUmakefile.list.am: Add missing header file.
+
+2012-03-05 Andy Wingo <wingo@igalia.com>
+
+ WTF: Micro-optimize cleanup of empty vectors and hash tables
+ https://bugs.webkit.org/show_bug.cgi?id=79903
+
+ Reviewed by Michael Saboff and Geoffrey Garen.
+
+ This patch speeds up cleanup of vectors and hash tables whose
+ backing store was never allocated. This is the case by default
+ for most vectors / hash tables that never had any entries added.
+
+ The result for me is that calling checkSyntax 1000 times on
+ concat-jquery-mootools-prototype.js goes from 6.234s to 6.068s, a
+ 2.4% speedup.
+
+ * wtf/HashTable.h:
+ (WTF::HashTable::~HashTable):
+ (WTF::::clear): Don't deallocate the storage or frob member
+ variables if there is no backing storage.
+ * wtf/Vector.h:
+ (WTF::VectorBufferBase::deallocateBuffer): Likewise.
+
+2012-03-04 Filip Pizlo <fpizlo@apple.com>
+
+ JIT heuristics should be hyperbolic
+ https://bugs.webkit.org/show_bug.cgi?id=80055
+ <rdar://problem/10922260>
+
+ Reviewed by Oliver Hunt.
+
+ Added tracking of the amount of executable memory typically used for a bytecode
+ instruction. Modified the execution counter scheme to use this, and the amount
+ of free memory, to determine how long to wait before invoking the JIT.
+
+ The result is that even if we bomb the VM with more code than can fit in our
+ executable memory pool, we still keep running and almost never run out of
+ executable memory - which ensures that if we have to JIT something critical, then
+ we'll likely have enough memory to do so. This also does not regress performance
+ on the three main benchmarks.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::predictedMachineCodeSize):
+ (JSC):
+ (JSC::CodeBlock::usesOpcode):
+ * bytecode/CodeBlock.h:
+ (CodeBlock):
+ (JSC::CodeBlock::checkIfJITThresholdReached):
+ (JSC::CodeBlock::dontJITAnytimeSoon):
+ (JSC::CodeBlock::jitAfterWarmUp):
+ (JSC::CodeBlock::jitSoon):
+ (JSC::CodeBlock::llintExecuteCounter):
+ (JSC::CodeBlock::counterValueForOptimizeAfterWarmUp):
+ (JSC::CodeBlock::counterValueForOptimizeAfterLongWarmUp):
+ (JSC::CodeBlock::addressOfJITExecuteCounter):
+ (JSC::CodeBlock::offsetOfJITExecuteCounter):
+ (JSC::CodeBlock::offsetOfJITExecutionActiveThreshold):
+ (JSC::CodeBlock::offsetOfJITExecutionTotalCount):
+ (JSC::CodeBlock::jitExecuteCounter):
+ (JSC::CodeBlock::checkIfOptimizationThresholdReached):
+ (JSC::CodeBlock::optimizeNextInvocation):
+ (JSC::CodeBlock::dontOptimizeAnytimeSoon):
+ (JSC::CodeBlock::optimizeAfterWarmUp):
+ (JSC::CodeBlock::optimizeAfterLongWarmUp):
+ (JSC::CodeBlock::optimizeSoon):
+ * bytecode/ExecutionCounter.cpp: Added.
+ (JSC):
+ (JSC::ExecutionCounter::ExecutionCounter):
+ (JSC::ExecutionCounter::checkIfThresholdCrossedAndSet):
+ (JSC::ExecutionCounter::setNewThreshold):
+ (JSC::ExecutionCounter::deferIndefinitely):
+ (JSC::ExecutionCounter::applyMemoryUsageHeuristics):
+ (JSC::ExecutionCounter::applyMemoryUsageHeuristicsAndConvertToInt):
+ (JSC::ExecutionCounter::hasCrossedThreshold):
+ (JSC::ExecutionCounter::setThreshold):
+ (JSC::ExecutionCounter::reset):
+ * bytecode/ExecutionCounter.h: Added.
+ (JSC):
+ (ExecutionCounter):
+ (JSC::ExecutionCounter::formattedTotalCount):
+ * dfg/DFGOSRExitCompiler32_64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+ * dfg/DFGOSRExitCompiler64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+ * jit/ExecutableAllocator.cpp:
+ (JSC::DemandExecutableAllocator::allocateNewSpace):
+ (JSC::ExecutableAllocator::underMemoryPressure):
+ (JSC):
+ (JSC::ExecutableAllocator::memoryPressureMultiplier):
+ * jit/ExecutableAllocator.h:
+ * jit/ExecutableAllocatorFixedVMPool.cpp:
+ (JSC::ExecutableAllocator::memoryPressureMultiplier):
+ (JSC):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompile):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::jitCompileAndSetHeuristics):
+ * llint/LowLevelInterpreter32_64.asm:
+ * runtime/JSGlobalData.h:
+ (JSGlobalData):
+ * runtime/Options.cpp:
+ (Options):
+ (JSC::Options::initializeOptions):
+ * runtime/Options.h:
+ (Options):
+ * wtf/SimpleStats.h: Added.
+ (WTF):
+ (SimpleStats):
+ (WTF::SimpleStats::SimpleStats):
+ (WTF::SimpleStats::add):
+ (WTF::SimpleStats::operator!):
+ (WTF::SimpleStats::count):
+ (WTF::SimpleStats::sum):
+ (WTF::SimpleStats::sumOfSquares):
+ (WTF::SimpleStats::mean):
+ (WTF::SimpleStats::variance):
+ (WTF::SimpleStats::standardDeviation):
+
+2012-03-04 Raphael Kubo da Costa <kubo@profusion.mobi>
+
+ [CMake] Libraries are installed to /usr/lib and not /usr/lib64 on x86_64
+ https://bugs.webkit.org/show_bug.cgi?id=71507
+
+ Reviewed by Antonio Gomes.
+
+ * CMakeLists.txt: Use ${LIB_INSTALL_DIR} instead of hardcoding "lib".
+
+2012-03-04 David Kilzer <ddkilzer@apple.com>
+
+ Fix build when the classic interpreter is enabled
+
+ Reviewed by Gavin Barraclough.
+
+ Fixes the following build error when running the "Generate
+ Derived Sources" build phase script:
+
+ offlineasm: Parsing JavaScriptCore/llint/LowLevelInterpreter.asm and ../../JSCLLIntOffsetsExtractor and creating assembly file LLIntAssembly.h.
+ ./JavaScriptCore/offlineasm/offsets.rb:145:in `offsetsAndConfigurationIndex': unhandled exception
+ from JavaScriptCore/offlineasm/asm.rb:131
+ Command /bin/sh failed with exit code 1
+
+ Gavin's fix in r109674 avoided the #error statement in
+ JITStubs.h when compiling LLIntOffsetsExtractor.cpp, but it
+ caused the "Generate Derived Sources" build phase script to fail
+ when JavaScriptCore/offlineasm/asm.rb was run. The solution is
+ to detect when the classic interpreter is being built and simply
+ exit early from asm.rb in that case.
+
+ * llint/LLIntOffsetsExtractor.cpp:
+ (JSC::LLIntOffsetsExtractor::dummy): Return NULL pointer if the
+ JIT is disabled. Note that offsets.rb doesn't care about the
+ return value here, but instead it cares about finding the magic
+ values in the binary. The magic values are no longer present
+ when the JIT is disabled.
+ * offlineasm/asm.rb: Catch MissingMagicValuesException and exit
+ early with a status message.
+ * offlineasm/offsets.rb:
+ (MissingMagicValuesException): Add new exception class.
+ (offsetsAndConfigurationIndex): Throw
+ MissingMagicValuesException when no magic values are found.
+
+2012-03-04 Jurij Smakov <jurij@wooyd.org>
+
+ SPARC also needs aligned accesses.
+
+ Rubber-stamped by Gustavo Noronha Silva.
+
+ * wtf/Platform.h:
+
+2012-03-04 Gavin Barraclough <barraclough@apple.com>
+
+ Unreviewed build fix.
+
+ * jit/JITStubs.h:
+ - Move ENABLE(JIT) to head of file.
+
+2012-03-03 Gavin Barraclough <barraclough@apple.com>
+
+ Split JSArray's [[Put]] & [[DefineOwnProperty]] traps.
+ https://bugs.webkit.org/show_bug.cgi?id=80217
+
+ Reviewed by Filip Pizlo.
+
+ putByIndex() provides similar behavior to put(), but for indexed property names.
+ Many places in ArrayPrototype call putByIndex() where they really mean to call
+ [[DefineOwnProperty]]. This is only okay due to a bug – putByIndex should be
+ calling numeric accessors (& respecting numeric read only properties) on the
+ prototype chain, but isn't. Add a new putDirectIndex (matching JSObject's
+ putDirect* methods), to correctly provide a fast [[DefineOwnProperty]] interface.
+
+ * runtime/ArrayPrototype.cpp:
+ (JSC::arrayProtoFuncConcat):
+ (JSC::arrayProtoFuncSlice):
+ (JSC::arrayProtoFuncFilter):
+ (JSC::arrayProtoFuncMap):
+ * runtime/JSArray.cpp:
+ (JSC):
+ (JSC::reject):
+ (JSC::SparseArrayValueMap::putDirect):
+ (JSC::JSArray::defineOwnNumericProperty):
+ (JSC::JSArray::putByIndexBeyondVectorLength):
+ (JSC::JSArray::putDirectIndexBeyondVectorLength):
+ * runtime/JSArray.h:
+ (SparseArrayValueMap):
+ (JSArray):
+ (JSC::JSArray::putDirectIndex):
+
+2012-03-03 Benjamin Poulain <benjamin@webkit.org>
+
+ Implement the basis of KURLWTFURL
+ https://bugs.webkit.org/show_bug.cgi?id=79600
+
+ Reviewed by Adam Barth.
+
+ Add an API to know if a ParsedURL is valid.
+
+ * wtf/url/api/ParsedURL.cpp:
+ (WTF::ParsedURL::ParsedURL):
+ (WTF):
+ (WTF::ParsedURL::isolatedCopy): This is needed by APIs moving URL objects between thread
+ and by KURL's detach() on write.
+ (WTF::ParsedURL::baseAsString):
+ (WTF::ParsedURL::segment):
+ Add a stronger constraint on accessors: the client of this API should never ask for the segments
+ on an invalid URL.
+ * wtf/url/api/ParsedURL.h:
+ (WTF):
+ (WTF::ParsedURL::ParsedURL):
+ (ParsedURL):
+ (WTF::ParsedURL::isValid):
+
+2012-03-03 Hans Wennborg <hans@chromium.org>
+
+ Implement Speech JavaScript API
+ https://bugs.webkit.org/show_bug.cgi?id=80019
+
+ Reviewed by Adam Barth.
+
+ Add ENABLE_SCRIPTED_SPEECH.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2012-03-02 Filip Pizlo <fpizlo@apple.com>
+
+ When getting the line number of a call into a call frame with no code block, it's
+ incorrect to rely on the returnPC
+ https://bugs.webkit.org/show_bug.cgi?id=80195
+
+ Reviewed by Oliver Hunt.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::getCallerInfo):
+ * jit/JITCall.cpp:
+ (JSC::JIT::compileLoadVarargs):
+
+2012-03-02 Han Hojong <hojong.han@samsung.com>
+
+ Expected results updated for checking type conversion
+ https://bugs.webkit.org/show_bug.cgi?id=80138
+
+ Reviewed by Gavin Barraclough.
+
+ * tests/mozilla/ecma/TypeConversion/9.3.1-3.js:
+
+2012-03-02 Kenichi Ishibashi <bashi@chromium.org>
+
+ Adding WebSocket per-frame DEFLATE extension
+ https://bugs.webkit.org/show_bug.cgi?id=77522
+
+ Added USE(ZLIB) flag.
+
+ Reviewed by Kent Tamura.
+
+ * wtf/Platform.h:
+
+2012-03-02 Filip Pizlo <fpizlo@apple.com>
+
+ Unreviewed build fix for platforms that have DFG_JIT disabled but PARALLEL_GC enabled.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::visitAggregate):
+
+2012-03-01 Filip Pizlo <fpizlo@apple.com>
+
+ DFGCodeBlocks should not trace CodeBlocks that are also going to be traced by
+ virtue of being in the transitive closure
+ https://bugs.webkit.org/show_bug.cgi?id=80098
+
+ Reviewed by Anders Carlsson.
+
+ If DFGCodeBlocks traces a CodeBlock that might also be traced via its owner Executable,
+ then you might have the visitAggregate() method called concurrently by multiple threads.
+ This is benign on 64-bit -- visitAggregate() and everything it calls turns out to be
+ racy and slightly imprecise but not unsound. But on 32-bit, visitAggregate() may crash
+ due to word tearing in ValueProfile bucket updates inside of computeUpdatedPrediction().
+
+ It would seem that the fix is just to have DFGCodeBlocks not trace CodeBlocks that are
+ not jettisoned. But CodeBlocks may be jettisoned later during the GC, so it must trace
+ any CodeBlock that it knows to be live by virtue of it being reachable from the stack.
+ Hence the real fix is to make sure that concurrent calls into CodeBlock::visitAggregate()
+ don't lead to two threads racing over each other as they clobber state. This patch
+ achieves this with a simple CAS loop: whichever thread wins the CAS race (which is
+ trivially linearizable) will get to trace the CodeBlock; all other threads give up and
+ go home.
+
+ Unfortunately there will be no new tests. It's possible to reproduce this maybe 1/10
+ times by running V8-v6's raytrace repeatedly, using the V8 harness hacked to rerun it
+ even when it's gotten sufficient counts. But that takes a while - sometimes up to a
+ minute to get a crash. I have no other reliable repro case.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::visitAggregate):
+ * bytecode/CodeBlock.h:
+ (DFGData):
+ * heap/DFGCodeBlocks.cpp:
+ (JSC::DFGCodeBlocks::clearMarks):
+
+2012-03-01 Filip Pizlo <fpizlo@apple.com>
+
+ The JIT should not crash the entire process just because there is not enough executable
+ memory, if the LLInt is enabled
+ https://bugs.webkit.org/show_bug.cgi?id=79962
+
+ Reviewed by Csaba Osztrogonác.
+
+ Fix for ARM, SH4.
+
+ * assembler/AssemblerBufferWithConstantPool.h:
+ (JSC::AssemblerBufferWithConstantPool::executableCopy):
+
+2012-03-01 Ryosuke Niwa <rniwa@webkit.org>
+
+ Revert my change. Broke builds.
+ Source/JavaScriptCore/wtf/Atomics.h:188: error: redefinition of 'bool WTF::weakCompareAndSwap(volatile uintptr_t*, uintptr_t, uintptr_t)'
+ Source/JavaScriptCore/wtf/Atomics.h:122: error: 'bool WTF::weakCompareAndSwap(volatile unsigned int*, unsigned int, unsigned i
+
+ * wtf/Atomics.h:
+ (WTF):
+ (WTF::weakCompareAndSwap):
+
+2012-03-01 Ryosuke Niwa <rniwa@webkit.org>
+
+ Gcc build fix.
+
+ Rubber-stamped by Filip Pizlo.
+
+ * wtf/Atomics.h:
+ (WTF):
+ (WTF::weakCompareAndSwap):
+
+2012-03-01 Gavin Barraclough <barraclough@apple.com>
+
+ ES5.1-15.3.5.4. prohibits Function.caller from [[Get]]ting a strict caller
+ https://bugs.webkit.org/show_bug.cgi?id=80011
+
+ Reviewed by Oliver Hunt.
+
+ Also, fix getting the caller from within a bound function, for within a getter,
+ or setter (make our implementation match other browsers).
+
+ * interpreter/Interpreter.cpp:
+ (JSC::getCallerInfo):
+ - Allow this to get the caller of host functions.
+ (JSC::Interpreter::retrieveCallerFromVMCode):
+ - This should use getCallerInfo, and should skip over function bindings.
+ * runtime/JSFunction.cpp:
+ (JSC::JSFunction::callerGetter):
+ - This should never return a strict-mode function.
+
+2012-03-01 Yuqiang Xian <yuqiang.xian@intel.com>
+
+ DFG local CSE for a node can be terminated earlier
+ https://bugs.webkit.org/show_bug.cgi?id=80014
+
+ Reviewed by Filip Pizlo.
+
+ When one of the node's childredn is met in the process of back traversing
+ the nodes, we don't need to traverse the remaining nodes.
+ This is performance neutral on SunSpider, V8 and Kraken.
+
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::pureCSE):
+ (JSC::DFG::CSEPhase::impureCSE):
+ (JSC::DFG::CSEPhase::getByValLoadElimination):
+ (JSC::DFG::CSEPhase::checkFunctionElimination):
+ (JSC::DFG::CSEPhase::checkStructureLoadElimination):
+ (JSC::DFG::CSEPhase::getByOffsetLoadElimination):
+ (JSC::DFG::CSEPhase::getPropertyStorageLoadElimination):
+ (JSC::DFG::CSEPhase::getIndexedPropertyStorageLoadElimination):
+
+2012-02-29 Yuqiang Xian <yuqiang.xian@intel.com>
+
+ DFG BasicBlocks should not require that their nodes have continuous indices in the graph
+ https://bugs.webkit.org/show_bug.cgi?id=79899
+
+ Reviewed by Filip Pizlo.
+
+ This will make it more convenient to insert nodes into the DFG.
+ With this capability we now place the Phi nodes in the corresponding
+ blocks.
+ Local CSE is modified to not to rely on the assumption of continuous
+ node indices in a block.
+ This is performance neutral on SunSpider, V8 and Kraken.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::AbstractState):
+ (JSC::DFG::AbstractState::beginBasicBlock):
+ (JSC::DFG::AbstractState::execute):
+ (JSC::DFG::AbstractState::clobberStructures):
+ (JSC::DFG::AbstractState::mergeToSuccessors):
+ (JSC::DFG::AbstractState::dump):
+ * dfg/DFGAbstractState.h:
+ (JSC::DFG::AbstractState::forNode):
+ (AbstractState):
+ * dfg/DFGArithNodeFlagsInferencePhase.cpp:
+ (ArithNodeFlagsInferencePhase):
+ * dfg/DFGBasicBlock.h:
+ (JSC::DFG::BasicBlock::BasicBlock):
+ (BasicBlock):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::addToGraph):
+ (ByteCodeParser):
+ (JSC::DFG::ByteCodeParser::insertPhiNode):
+ (JSC::DFG::ByteCodeParser::handleInlining):
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ (JSC::DFG::ByteCodeParser::processPhiStack):
+ (JSC::DFG::ByteCodeParser::linkBlock):
+ (JSC::DFG::ByteCodeParser::determineReachability):
+ (JSC::DFG::ByteCodeParser::parseCodeBlock):
+ * dfg/DFGCFAPhase.cpp:
+ (JSC::DFG::CFAPhase::performBlockCFA):
+ (CFAPhase):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::CSEPhase):
+ (JSC::DFG::CSEPhase::endIndexForPureCSE):
+ (JSC::DFG::CSEPhase::pureCSE):
+ (JSC::DFG::CSEPhase::impureCSE):
+ (JSC::DFG::CSEPhase::globalVarLoadElimination):
+ (JSC::DFG::CSEPhase::getByValLoadElimination):
+ (JSC::DFG::CSEPhase::checkFunctionElimination):
+ (JSC::DFG::CSEPhase::checkStructureLoadElimination):
+ (JSC::DFG::CSEPhase::getByOffsetLoadElimination):
+ (JSC::DFG::CSEPhase::getPropertyStorageLoadElimination):
+ (JSC::DFG::CSEPhase::getIndexedPropertyStorageLoadElimination):
+ (JSC::DFG::CSEPhase::getScopeChainLoadElimination):
+ (JSC::DFG::CSEPhase::performNodeCSE):
+ (JSC::DFG::CSEPhase::performBlockCSE):
+ (CSEPhase):
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::Graph::dump):
+ * dfg/DFGPhase.cpp:
+ (JSC::DFG::Phase::beginPhase):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeCompare):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeStrictEq):
+ (JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):
+ (JSC::DFG::SpeculativeJIT::compile):
+ (JSC::DFG::SpeculativeJIT::compileStrictEqForConstant):
+ (JSC::DFG::SpeculativeJIT::compileStrictEq):
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+ (JSC::DFG::SpeculativeJIT::detectPeepHoleBranch):
+ (JSC::DFG::SpeculativeJIT::SpeculativeJIT):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeCompareNull):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeCompareNull):
+ * dfg/DFGVirtualRegisterAllocationPhase.cpp:
+ (JSC::DFG::VirtualRegisterAllocationPhase::run):
+
+2012-02-29 Filip Pizlo <fpizlo@apple.com>
+
+ The JIT should not crash the entire process just because there is not
+ enough executable memory, if the LLInt is enabled
+ https://bugs.webkit.org/show_bug.cgi?id=79962
+ <rdar://problem/10922215>
+
+ Unreviewed, adding forgotten file.
+
+ * jit/JITCompilationEffort.h: Added.
+ (JSC):
+
+2012-02-29 Filip Pizlo <fpizlo@apple.com>
+
+ The JIT should not crash the entire process just because there is not
+ enough executable memory, if the LLInt is enabled
+ https://bugs.webkit.org/show_bug.cgi?id=79962
+ <rdar://problem/10922215>
+
+ Reviewed by Gavin Barraclough.
+
+ Added the notion of JITCompilationEffort. If we're JIT'ing as a result of
+ a tier-up, then we set it to JITCompilationCanFail. Otherwise it's
+ JITCompilationMustSucceed. This preserves the old behavior of LLInt is
+ disabled or if we're compiling something that can't be interpreted (like
+ an OSR exit stub).
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * assembler/ARMAssembler.cpp:
+ (JSC::ARMAssembler::executableCopy):
+ * assembler/ARMAssembler.h:
+ (ARMAssembler):
+ * assembler/AssemblerBuffer.h:
+ (JSC::AssemblerBuffer::executableCopy):
+ * assembler/LinkBuffer.h:
+ (JSC::LinkBuffer::LinkBuffer):
+ (JSC::LinkBuffer::~LinkBuffer):
+ (LinkBuffer):
+ (JSC::LinkBuffer::didFailToAllocate):
+ (JSC::LinkBuffer::isValid):
+ (JSC::LinkBuffer::linkCode):
+ (JSC::LinkBuffer::performFinalization):
+ * assembler/MIPSAssembler.h:
+ (JSC::MIPSAssembler::executableCopy):
+ * assembler/SH4Assembler.h:
+ (JSC::SH4Assembler::executableCopy):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::executableCopy):
+ (JSC::X86Assembler::X86InstructionFormatter::executableCopy):
+ * bytecode/CodeBlock.cpp:
+ (JSC::ProgramCodeBlock::jitCompileImpl):
+ (JSC::EvalCodeBlock::jitCompileImpl):
+ (JSC::FunctionCodeBlock::jitCompileImpl):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::jitCompile):
+ (CodeBlock):
+ (ProgramCodeBlock):
+ (EvalCodeBlock):
+ (FunctionCodeBlock):
+ * dfg/DFGDriver.cpp:
+ (JSC::DFG::compile):
+ * dfg/DFGJITCompiler.cpp:
+ (JSC::DFG::JITCompiler::compile):
+ (JSC::DFG::JITCompiler::compileFunction):
+ * dfg/DFGJITCompiler.h:
+ (JITCompiler):
+ * jit/ExecutableAllocator.cpp:
+ (JSC::DemandExecutableAllocator::allocateNewSpace):
+ (JSC::ExecutableAllocator::allocate):
+ * jit/ExecutableAllocator.h:
+ (ExecutableAllocator):
+ * jit/ExecutableAllocatorFixedVMPool.cpp:
+ (JSC::ExecutableAllocator::allocate):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompile):
+ * jit/JIT.h:
+ (JSC::JIT::compile):
+ (JIT):
+ * jit/JITCompilationEffort.h: Added.
+ (JSC):
+ * jit/JITDriver.h:
+ (JSC::jitCompileIfAppropriate):
+ (JSC::jitCompileFunctionIfAppropriate):
+ * llint/LLIntSlowPaths.cpp:
+ (LLInt):
+ (JSC::LLInt::jitCompileAndSetHeuristics):
+ (JSC::LLInt::entryOSR):
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ * runtime/Executable.cpp:
+ (JSC::EvalExecutable::jitCompile):
+ (JSC::ProgramExecutable::jitCompile):
+ (JSC::FunctionExecutable::jitCompileForCall):
+ (JSC::FunctionExecutable::jitCompileForConstruct):
+ * runtime/Executable.h:
+ (EvalExecutable):
+ (ProgramExecutable):
+ (FunctionExecutable):
+ (JSC::FunctionExecutable::jitCompileFor):
+ * runtime/ExecutionHarness.h:
+ (JSC::prepareForExecution):
+ (JSC::prepareFunctionForExecution):
+
+2012-02-29 No'am Rosenthal <noam.rosenthal@nokia.com>
+
+ [Qt][WK2] Get rid of the #ifdef mess in LayerTreeHost[Proxy]
+ https://bugs.webkit.org/show_bug.cgi?id=79501
+
+ Enable WTF_USE_UI_SIDE_COMPOSITING for Qt.
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ * wtf/Platform.h:
+
+2012-02-29 Gavin Barraclough <barraclough@apple.com>
+
+ Rubber stamped by Oliver Hunt.
+
+ * tests/mozilla/ecma_2/RegExp/constructor-001.js:
+ * tests/mozilla/ecma_2/RegExp/function-001.js:
+ * tests/mozilla/ecma_2/RegExp/properties-001.js:
+ - Check in new test cases results.
+
+2012-02-29 Mark Rowe <mrowe@apple.com>
+
+ Stop installing JSCLLIntOffsetsExtractor.
+
+ Replace the separate TestRegExp and TestAPI xcconfig files with a single ToolExecutable xcconfig file
+ that derives the product name from the target name. We can then use that xcconfig file for JSCLLIntOffsetsExtractor.
+ This has the results of setting SKIP_INSTALL = YES for JSCLLIntOffsetsExtractor.
+
+ While I was doing this fiddling I noticed that the JSCLLIntOffsetsExtractor target had a custom value
+ for USER_HEADER_SEARCH_PATHS to allow it to find LLIntDesiredOffsets.h. A better way of doing that is
+ to add LLIntDesiredOffsets.h to the Xcode project so that it'll be included in the header map. That
+ allows us to remove the override of USER_HEADER_SEARCH_PATHS entirely. So I did that too!
+
+ Reviewed by Filip Pizlo.
+
+ * Configurations/TestRegExp.xcconfig: Removed.
+ * Configurations/ToolExecutable.xcconfig: Renamed from Source/JavaScriptCore/Configurations/TestAPI.xcconfig.
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2012-02-28 Filip Pizlo <fpizlo@apple.com>
+
+ RefCounted::deprecatedTurnOffVerifier() should not be deprecated
+ https://bugs.webkit.org/show_bug.cgi?id=79864
+
+ Reviewed by Oliver Hunt.
+
+ Removed the word "deprecated" from the name of this method, since this method
+ should not be deprecated. It works just fine as it is, and there is simply no
+ alternative to calling this method for many interesting JSC classes.
+
+ * parser/SourceProvider.h:
+ (JSC::SourceProvider::SourceProvider):
+ * runtime/SymbolTable.h:
+ (JSC::SharedSymbolTable::SharedSymbolTable):
+ * wtf/MetaAllocator.cpp:
+ (WTF::MetaAllocatorHandle::MetaAllocatorHandle):
+ (WTF::MetaAllocator::allocate):
+ * wtf/RefCounted.h:
+ (RefCountedBase):
+ (WTF::RefCountedBase::turnOffVerifier):
+
+2012-02-29 Gavin Barraclough <barraclough@apple.com>
+
+ 'source' property of RegExp instance cannot be ""
+ https://bugs.webkit.org/show_bug.cgi?id=79938
+
+ Reviewed by Oliver Hunt.
+
+ 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.
+
+ * runtime/RegExpObject.cpp:
+ (JSC::regExpObjectSource):
+ - Do not return "" if the source is empty, this would lead to invalid behaviour in toString.
+ * runtime/RegExpPrototype.cpp:
+ (JSC::regExpProtoFuncToString):
+ - No need to special case the empty string - this should be being done by 'source'.
+
+2012-02-29 Gavin Barraclough <barraclough@apple.com>
+
+ Writable attribute not set correctly when redefining an accessor to a data descriptor
+ https://bugs.webkit.org/show_bug.cgi?id=79931
+
+ Reviewed by Oliver Hunt.
+
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::defineOwnProperty):
+ - use attributesOverridingCurrent instead of attributesWithOverride.
+ * runtime/PropertyDescriptor.cpp:
+ * runtime/PropertyDescriptor.h:
+ - remove attributesWithOverride - attributesOverridingCurrent does the same thing.
+
+2012-02-29 Kevin Ollivier <kevino@theolliviers.com>
+
+ Add JSCore symbol exports needed by wx port
+ https://bugs.webkit.org/show_bug.cgi?id=77280
+
+ Reviewed by Hajime Morita.
+
+ * wtf/ArrayBufferView.h:
+ * wtf/ExportMacros.h:
+
+2012-02-28 Raphael Kubo da Costa <kubo@profusion.mobi>
+
+ [CMake] Always build wtf as a static library.
+ https://bugs.webkit.org/show_bug.cgi?id=79857
+
+ Reviewed by Eric Seidel.
+
+ To help the efforts in bug 75673 to move WTF out of
+ JavaScriptCore, act more like the other ports and remove the
+ possibility of building WTF as a shared library.
+
+ It does not make much sense to, for example, ship WTF as a
+ separate .so with webkit-efl packages, and it should be small
+ enough not to cause problems during linking.
+
+ * wtf/CMakeLists.txt:
+
+2012-02-28 Dmitry Lomov <dslomov@google.com>
+
+ [JSC] Implement ArrayBuffer transfer
+ https://bugs.webkit.org/show_bug.cgi?id=73493.
+ Implement ArrayBuffer transfer, per Khronos spec: http://www.khronos.org/registry/typedarray/specs/latest/#9.
+ This brings parity with V8 implementation of transferable typed arrays.
+
+ Reviewed by Oliver Hunt.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: Extra export.
+ * wtf/ArrayBuffer.h:
+ (ArrayBuffer): Added extra export.
+
+2012-02-28 Kevin Ollivier <kevino@theolliviers.com>
+
+ [wx] Unreviewed. Build fix after recent LLInt additions.
+
+ * wscript:
+
+2012-02-28 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Refactor SpeculativeJIT::emitAllocateJSFinalObject
+ https://bugs.webkit.org/show_bug.cgi?id=79801
+
+ Reviewed by Filip Pizlo.
+
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject): Split emitAllocateJSFinalObject out to form this
+ function, which is more generic in that it can allocate a variety of classes.
+ (SpeculativeJIT):
+ (JSC::DFG::SpeculativeJIT::emitAllocateJSFinalObject): Changed to use the new helper function.
+
+2012-02-28 Gavin Barraclough <barraclough@apple.com>
+
+ [[Get]]/[[Put]] for primitives should not wrap on strict accessor call
+ https://bugs.webkit.org/show_bug.cgi?id=79588
+
+ Reviewed by Oliver Hunt.
+
+ In the case of [[Get]], this is a pretty trivial bug - just don't wrap
+ primitives at the point you call a getter.
+
+ For setters, this is a little more involved, since we have already wrapped
+ the value up in a synthesized object. Stop doing so. There is also a further
+ subtely, that in strict mode all attempts to create a new data property on
+ the object should throw.
+
+ * runtime/JSCell.cpp:
+ (JSC::JSCell::put):
+ - [[Put]] to a string primitive should use JSValue::putToPrimitive.
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::put):
+ - Remove static function called in one place.
+ * runtime/JSObject.h:
+ (JSC::JSValue::put):
+ - [[Put]] to a non-cell JSValue should use JSValue::putToPrimitive.
+ * runtime/JSValue.cpp:
+ (JSC::JSValue::synthesizePrototype):
+ - Add support for synthesizing the prototype of strings.
+ (JSC::JSValue::putToPrimitive):
+ - Added, implements [[Put]] for primitive bases, per 8.7.2.
+ * runtime/JSValue.h:
+ (JSValue):
+ - Add declaration for JSValue::putToPrimitive.
+ * runtime/PropertySlot.cpp:
+ (JSC::PropertySlot::functionGetter):
+ - Don't call ToObject on primitive this values.
+
+2012-02-28 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Re-enable parallel GC on Mac
+ https://bugs.webkit.org/show_bug.cgi?id=79837
+
+ Rubber stamped by Filip Pizlo.
+
+ * runtime/Options.cpp:
+ (JSC::Options::initializeOptions): We accidentally disabled parallel GC with this line,
+ so we removed it and things should go back to normal.
+
+2012-02-28 Filip Pizlo <fpizlo@apple.com>
+
+ Some run-javascriptcore-tests broken for 32-bit debug
+ https://bugs.webkit.org/show_bug.cgi?id=79844
+
+ Rubber stamped by Oliver Hunt.
+
+ These assertions are just plain wrong for 32-bit. We could either have a massive
+ assertion that depends on value representation, that has to be changed every
+ time we change the JITs, resulting in a bug tail of debug-mode crashes, or we
+ could get rid of the assertions. I pick the latter.
+
+ * dfg/DFGOperations.cpp:
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+
+2012-02-28 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Get rid of padding cruft in CopiedBlock
+ https://bugs.webkit.org/show_bug.cgi?id=79686
+
+ Reviewed by Filip Pizlo.
+
+ * heap/CopiedBlock.h:
+ (CopiedBlock): Removed the extra padding that was used for alignment purposes until
+ the calculation of the payload offset into CopiedBlocks was redone recently.
+
+2012-02-28 Anders Carlsson <andersca@apple.com>
+
+ Fix build with newer versions of clang.
+
+ Clang now warns since we're not passing a CFString literal to CFStringCreateWithFormatAndArguments,
+ but it's OK to ignore this warning since clang is also checking that the caller (vprintf_stderr_common)
+ takes a string literal.
+
+ * wtf/Assertions.cpp:
+
+2012-02-28 Mario Sanchez Prada <msanchez@igalia.com>
+
+ [GTK] Add GMainLoop and GMainContext to be handled by GRefPtr
+ https://bugs.webkit.org/show_bug.cgi?id=79496
+
+ Reviewed by Martin Robinson.
+
+ Handle GMainLoop and GMainContext in GRefPtr, by calling
+ g_main_loop_(un)ref and g_main_context_(un)ref in the
+ implementation of the refGPtr and derefGPtr template functions.
+
+ * wtf/gobject/GRefPtr.cpp:
+ (WTF::refGPtr):
+ (WTF):
+ (WTF::derefGPtr):
+ * wtf/gobject/GRefPtr.h:
+ (WTF):
+ * wtf/gobject/GTypedefs.h:
+
+2012-02-28 Yong Li <yoli@rim.com>
+
+ JSString::resolveRope() should report extra memory cost to the heap.
+ https://bugs.webkit.org/show_bug.cgi?id=79555
+
+ Reviewed by Michael Saboff.
+
+ At the time a JSString is constructed with fibers, it doesn't report
+ extra memory cost, which is reasonable because it hasn't allocate
+ new memory. However when the rope is resolved, it should report meory
+ cost for the new buffer.
+
+ * runtime/JSString.cpp:
+ (JSC::JSString::resolveRope):
+
+2012-02-27 Oliver Hunt <oliver@apple.com>
+
+ sputnik/Unicode/Unicode_500/S7.2_A1.6_T1.html crashes in the interpreter
+ https://bugs.webkit.org/show_bug.cgi?id=79728
+
+ Reviewed by Gavin Barraclough.
+
+ When initialising a chained get instruction we may end up in a state where
+ the instruction stream says we have a scopechain, but it has not yet been set
+ (eg. if allocating the StructureChain itself is what leads to the GC). We could
+ re-order the allocation, but it occurs in a couple of places, so it seems less
+ fragile simply to null check the scopechain slot before we actually visit the slot.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::visitStructures):
+
+2012-02-27 Filip Pizlo <fpizlo@apple.com>
+
+ Old JIT's style of JSVALUE64 strict equality is subtly wrong
+ https://bugs.webkit.org/show_bug.cgi?id=79700
+
+ Reviewed by Oliver Hunt.
+
+ * assembler/MacroAssemblerX86_64.h:
+ (JSC::MacroAssemblerX86_64::comparePtr):
+ (MacroAssemblerX86_64):
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeStrictEq):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeStrictEq):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeStrictEq):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::compileOpStrictEq):
+ (JSC::JIT::emitSlow_op_stricteq):
+ (JSC::JIT::emitSlow_op_nstricteq):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+
+2012-02-27 Gavin Barraclough <barraclough@apple.com>
+
+ Implement support for op_negate and op_bitnot in the DFG JIT
+ https://bugs.webkit.org/show_bug.cgi?id=79617
+
+ Reviewed by Filip Pizlo.
+
+ Add an ArithNegate op to the DFG JIT, to implement op_negate.
+
+ This patch also adds support for op_negate to the JSVALUE64 baseline JIT
+ (JSVALUE32_64 already had this), so that we can profile the slowpath usage.
+
+ This is a 2.5%-3% Sunspider progression and a 1% win on Kraken.
+
+ * assembler/ARMv7Assembler.h:
+ (JSC::ARMv7Assembler::sub_S):
+ - Added sub_S from immediate.
+ (ARMv7Assembler):
+ (JSC::ARMv7Assembler::vneg):
+ - Added double negate.
+ * assembler/MacroAssemblerARMv7.h:
+ (JSC::MacroAssemblerARMv7::negateDouble):
+ - Added double negate.
+ (MacroAssemblerARMv7):
+ (JSC::MacroAssemblerARMv7::branchNeg32):
+ - Added.
+ * assembler/MacroAssemblerX86.h:
+ (MacroAssemblerX86):
+ - moved loadDouble, absDouble to common.
+ * assembler/MacroAssemblerX86Common.h:
+ (MacroAssemblerX86Common):
+ (JSC::MacroAssemblerX86Common::absDouble):
+ - implementation can be shared.
+ (JSC::MacroAssemblerX86Common::negateDouble):
+ - Added.
+ (JSC::MacroAssemblerX86Common::loadDouble):
+ - allow absDouble to have a common implementation.
+ * assembler/MacroAssemblerX86_64.h:
+ (MacroAssemblerX86_64):
+ - moved loadDouble, absDouble to common.
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ - support ArithNegate.
+ * dfg/DFGArithNodeFlagsInferencePhase.cpp:
+ (JSC::DFG::ArithNodeFlagsInferencePhase::propagate):
+ - support ArithNegate.
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::makeSafe):
+ - support ArithNegate.
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ - support op_negate.
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::performNodeCSE):
+ - support ArithNegate.
+ * dfg/DFGCapabilities.h:
+ (JSC::DFG::canCompileOpcode):
+ - support op_negate.
+ * dfg/DFGGraph.h:
+ (JSC::DFG::Graph::negateShouldSpeculateInteger):
+ - support ArithNegate.
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::hasArithNodeFlags):
+ - support ArithNegate.
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ - support ArithNegate.
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileArithNegate):
+ - support ArithNegate.
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+ - support ArithNegate.
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ - support ArithNegate.
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ - support ArithNegate.
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ - Add support for op_negate in JSVALUE64.
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::emit_op_negate):
+ (JSC::JIT::emitSlow_op_negate):
+ - Add support for op_negate in JSVALUE64.
+
+2012-02-27 Mahesh Kulkarni <mahesh.kulkarni@nokia.com>
+
+ Unreviewed. Build fix for linux-bot (qt) after r109021.
+
+ * runtime/Error.cpp:
+
+2012-02-27 Oliver Hunt <oliver@apple.com>
+
+ REGRESSION (r108112): AWS Management Console at amazon.com fails to initialize
+ https://bugs.webkit.org/show_bug.cgi?id=79693
+
+ Reviewed by Filip Pizlo.
+
+ Alas we can't provide the stack trace as an array, as despite everyone wanting
+ an array, everyone arbitrarily creates the array by calling split on the stack
+ trace. To create the array we would have provided them in the first place.
+
+ This changes the exception's stack property to a \n separated string. To get the
+ old array just do <exception>.stack.split("\n").
+
+ * runtime/Error.cpp:
+ (JSC::addErrorInfo):
+
+2012-02-27 Gavin Barraclough <barraclough@apple.com>
+
+ RegExp lastIndex should behave as a regular property
+ https://bugs.webkit.org/show_bug.cgi?id=79446
+
+ Reviewed by Sam Weinig.
+
+ lastIndex should be a regular data descriptor, with the attributes configurable:false,
+ enumerable:false, writable:true. As such, it should be possible to reconfigure writable
+ as false. If the lastIndex property is reconfigured to be read-only, we should respect
+ this correctly.
+
+ * runtime/CommonIdentifiers.h:
+ - Removed some unused identifiers, added lastIndex.
+ * runtime/RegExpObject.cpp:
+ (JSC::RegExpObject::getOwnPropertySlot):
+ - lastIndex is no longer a static value, provided specific handling.
+ (JSC::RegExpObject::getOwnPropertyDescriptor):
+ - lastIndex is no longer a static value, provided specific handling.
+ (JSC::RegExpObject::deleteProperty):
+ - lastIndex is no longer a static value, provided specific handling.
+ (JSC::RegExpObject::getOwnPropertyNames):
+ - lastIndex is no longer a static value, provided specific handling.
+ (JSC::RegExpObject::getPropertyNames):
+ - lastIndex is no longer a static value, provided specific handling.
+ (JSC::reject):
+ - helper function for defineOwnProperty.
+ (JSC::RegExpObject::defineOwnProperty):
+ - lastIndex is no longer a static value, provided specific handling.
+ (JSC::RegExpObject::put):
+ - lastIndex is no longer a static value, provided specific handling.
+ (JSC::RegExpObject::match):
+ - Pass setLastIndex an ExecState, so it can throw if read-only.
+ * runtime/RegExpObject.h:
+ (JSC::RegExpObject::setLastIndex):
+ - Pass setLastIndex an ExecState, so it can throw if read-only.
+ (RegExpObjectData):
+ - Added lastIndexIsWritable.
+ * runtime/RegExpPrototype.cpp:
+ (JSC::regExpProtoFuncCompile):
+ - Pass setLastIndex an ExecState, so it can throw if read-only.
+
+2012-02-27 Gavin Barraclough <barraclough@apple.com>
+
+ Implement support for op_negate and op_bitnot in the DFG JIT
+ https://bugs.webkit.org/show_bug.cgi?id=79617
+
+ Reviewed by Sam Weinig.
+
+ Remove op_bitnop - this is redundant, ~x === x^-1.
+ This is a fractional (<1%) progression.
+
+ Remove not32(X) from the MacroAssemblers - make this an optimization to add32(-1, X).
+ Remove CanReuse from the result type - this was unused.
+ Remove op_bitnot.
+
+ * assembler/MacroAssemblerARM.h:
+ (MacroAssemblerARM):
+ (JSC::MacroAssemblerARM::xor32):
+ * assembler/MacroAssemblerARMv7.h:
+ (MacroAssemblerARMv7):
+ (JSC::MacroAssemblerARMv7::xor32):
+ * assembler/MacroAssemblerMIPS.h:
+ (MacroAssemblerMIPS):
+ (JSC::MacroAssemblerMIPS::xor32):
+ * assembler/MacroAssemblerSH4.h:
+ (MacroAssemblerSH4):
+ (JSC::MacroAssemblerSH4::xor32):
+ * assembler/MacroAssemblerX86Common.h:
+ (MacroAssemblerX86Common):
+ (JSC::MacroAssemblerX86Common::xor32):
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ * bytecode/Opcode.h:
+ (JSC):
+ (JSC::padOpcodeName):
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC):
+ (JSC::BitwiseNotNode::emitBytecode):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ * jit/JIT.h:
+ (JIT):
+ * jit/JITArithmetic32_64.cpp:
+ (JSC):
+ * jit/JITOpcodes.cpp:
+ (JSC):
+ * jit/JITStubs.cpp:
+ (JSC):
+ * jit/JITStubs.h:
+ * llint/LLIntSlowPaths.cpp:
+ (LLInt):
+ * llint/LLIntSlowPaths.h:
+ (LLInt):
+ * llint/LowLevelInterpreter32_64.asm:
+ * parser/NodeConstructors.h:
+ (JSC::NegateNode::NegateNode):
+ (JSC::BitwiseNotNode::BitwiseNotNode):
+ (JSC::MultNode::MultNode):
+ (JSC::DivNode::DivNode):
+ (JSC::ModNode::ModNode):
+ (JSC::SubNode::SubNode):
+ (JSC::UnsignedRightShiftNode::UnsignedRightShiftNode):
+ * parser/Nodes.h:
+ (BitwiseNotNode):
+ (JSC::BitwiseNotNode::expr):
+ (JSC):
+ * parser/ResultType.h:
+ (ResultType):
+ (JSC::ResultType::numberTypeIsInt32):
+ (JSC::ResultType::stringOrNumberType):
+ (JSC::ResultType::forAdd):
+ (JSC::ResultType::forBitOp):
+
+2012-02-27 Michael Saboff <msaboff@apple.com>
+
+ Error check regexp min quantifier
+ https://bugs.webkit.org/show_bug.cgi?id=70648
+
+ Reviewed by Gavin Barraclough.
+
+ Added checking for min or only quantifier being UINT_MAX.
+ When encountered this becomes a SyntaxError during parsing.
+
+ * yarr/YarrParser.h:
+ (JSC::Yarr::Parser::parseQuantifier):
+ (JSC::Yarr::Parser::parse):
+ (Parser):
+
+2012-02-27 Carlos Garcia Campos <cgarcia@igalia.com>
+
+ Unreviewed. Fix make distcheck.
+
+ * GNUmakefile.list.am: Add missing files.
+
+2012-02-26 Hajime Morrita <morrita@chromium.org>
+
+ Move ChromeClient::showContextMenu() to ContextMenuClient
+ https://bugs.webkit.org/show_bug.cgi?id=79427
+
+ Reviewed by Adam Barth.
+
+ Added ACCESSIBILITY_CONTEXT_MENUS.
+
+ * wtf/Platform.h:
+
+2012-02-26 Filip Pizlo <fpizlo@apple.com>
+
+ LayoutTests/fast/xpath/xpath-functional-test.html is crashing in the DFG
+ https://bugs.webkit.org/show_bug.cgi?id=79616
+
+ Reviewed by Oliver Hunt.
+
+ Guard against the fact that in JSVALUE64, JSValue().isCell() == true.
+
+ * dfg/DFGAbstractValue.h:
+ (JSC::DFG::AbstractValue::validate):
+
+2012-02-26 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should support activations and nested functions
+ https://bugs.webkit.org/show_bug.cgi?id=79554
+
+ Reviewed by Sam Weinig.
+
+ Fix 32-bit. The 32-bit function+activation code had some really weird
+ register reuse bugs.
+
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2012-02-26 Filip Pizlo <fpizlo@apple.com>
+
+ Getting the instruction stream for a code block should not require two loads
+ https://bugs.webkit.org/show_bug.cgi?id=79608
+
+ Reviewed by Sam Weinig.
+
+ Introduced the RefCountedArray class, which contains a single inline pointer
+ to a ref-counted non-resizeable vector backing store. This satisfies the
+ requirements of CodeBlock, which desires the ability to share instruction
+ streams with other CodeBlocks. It also reduces the number of loads required
+ for getting the instruction stream by one.
+
+ This patch also gets rid of the bytecode discarding logic, since we don't
+ use it anymore and it's unlikely to ever work right with DFG or LLInt. And
+ I didn't feel like porting dead code to use RefCountedArray.
+
+ * GNUmakefile.list.am:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * bytecode/CodeBlock.cpp:
+ (JSC::instructionOffsetForNth):
+ (JSC::CodeBlock::dump):
+ (JSC::CodeBlock::CodeBlock):
+ (JSC::CodeBlock::finalizeUnconditionally):
+ (JSC::CodeBlock::handlerForBytecodeOffset):
+ (JSC::CodeBlock::lineNumberForBytecodeOffset):
+ (JSC::CodeBlock::expressionRangeForBytecodeOffset):
+ (JSC::CodeBlock::shrinkToFit):
+ * bytecode/CodeBlock.h:
+ (CodeBlock):
+ (JSC::CodeBlock::numberOfInstructions):
+ (JSC::CodeBlock::instructions):
+ (JSC::CodeBlock::instructionCount):
+ (JSC::CodeBlock::valueProfileForBytecodeOffset):
+ (JSC):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::Label::setLocation):
+ (JSC):
+ (JSC::BytecodeGenerator::generate):
+ (JSC::BytecodeGenerator::newLabel):
+ * bytecompiler/BytecodeGenerator.h:
+ (JSC):
+ (BytecodeGenerator):
+ (JSC::BytecodeGenerator::instructions):
+ * bytecompiler/Label.h:
+ (JSC::Label::Label):
+ (Label):
+ * dfg/DFGByteCodeCache.h:
+ (JSC::DFG::ByteCodeCache::~ByteCodeCache):
+ (JSC::DFG::ByteCodeCache::get):
+ * jit/JITExceptions.cpp:
+ (JSC::genericThrow):
+ * llint/LowLevelInterpreter32_64.asm:
+ * runtime/Executable.cpp:
+ (JSC::EvalExecutable::compileInternal):
+ (JSC::ProgramExecutable::compileInternal):
+ (JSC::FunctionExecutable::codeBlockWithBytecodeFor):
+ (JSC::FunctionExecutable::produceCodeBlockFor):
+ * wtf/RefCountedArray.h: Added.
+ (WTF):
+ (RefCountedArray):
+ (WTF::RefCountedArray::RefCountedArray):
+ (WTF::RefCountedArray::operator=):
+ (WTF::RefCountedArray::~RefCountedArray):
+ (WTF::RefCountedArray::size):
+ (WTF::RefCountedArray::data):
+ (WTF::RefCountedArray::begin):
+ (WTF::RefCountedArray::end):
+ (WTF::RefCountedArray::at):
+ (WTF::RefCountedArray::operator[]):
+ (Header):
+ (WTF::RefCountedArray::Header::size):
+ (WTF::RefCountedArray::Header::payload):
+ (WTF::RefCountedArray::Header::fromPayload):
+ * wtf/Platform.h:
+
+2012-02-26 Yusuke Suzuki <utatane.tea@gmail.com>
+
+ StringLiteral and NumericLiteral are allowed as ObjectLiteral getter / setter name
+ https://bugs.webkit.org/show_bug.cgi?id=79571
+
+ Reviewed by Gavin Barraclough.
+
+ * parser/ASTBuilder.h:
+ (JSC::ASTBuilder::createGetterOrSetterProperty):
+ * parser/Parser.cpp:
+ (JSC::::parseProperty):
+ * parser/SyntaxChecker.h:
+ (JSC::SyntaxChecker::createGetterOrSetterProperty):
+
+2012-02-26 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Implement fast path for op_new_array in the baseline JIT
+ https://bugs.webkit.org/show_bug.cgi?id=78612
+
+ Reviewed by Filip Pizlo.
+
+ heap/CopiedAllocator.h:
+ (CopiedAllocator): Friended the JIT to allow access to m_currentOffset.
+ * heap/CopiedSpace.h:
+ (CopiedSpace): Friended the JIT to allow access to isOversize.
+ (JSC::CopiedSpace::allocator):
+ * heap/Heap.h:
+ (JSC::Heap::storageAllocator): Added a getter for the CopiedAllocator class so the JIT
+ can use it for simple allocation i.e. when we can just bump the offset without having to
+ do anything else.
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileSlowCases): Added new slow case for op_new_array for when
+ we have to bail out because the fast allocation path fails for whatever reason.
+ * jit/JIT.h:
+ (JIT):
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitAllocateBasicStorage): Added utility function that allows objects to
+ allocate generic backing stores. This function is used by emitAllocateJSArray.
+ (JSC):
+ (JSC::JIT::emitAllocateJSArray): Added utility function that allows the client to
+ more easily allocate JSArrays. This function is used by emit_op_new_array and I expect
+ it will also be used for emit_op_new_array_buffer.
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_new_array): Changed to do inline allocation of JSArrays. Still does
+ a stub call for oversize arrays.
+ (JSC):
+ (JSC::JIT::emitSlow_op_new_array): New slow path that just bails out to a stub call if we
+ fail in any way on the fast path.
+ * runtime/JSArray.cpp:
+ (JSC):
+ * runtime/JSArray.h: Added lots of offset functions for all the fields that we need to
+ initialize in the JIT.
+ (ArrayStorage):
+ (JSC::ArrayStorage::lengthOffset):
+ (JSC::ArrayStorage::numValuesInVectorOffset):
+ (JSC::ArrayStorage::allocBaseOffset):
+ (JSC::ArrayStorage::vectorOffset):
+ (JSArray):
+ (JSC::JSArray::sparseValueMapOffset):
+ (JSC::JSArray::subclassDataOffset):
+ (JSC::JSArray::indexBiasOffset):
+ (JSC):
+ (JSC::JSArray::storageSize): Moved this function from being a static function in the cpp file
+ to being a static function in the JSArray class. This move allows the JIT to call it to
+ see what size it should allocate.
+
+2012-02-26 Patrick Gansterer <paroga@webkit.org>
+
+ Unreviewed. Build fix for ENABLE(CLASSIC_INTERPRETER) after r108681.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::getLineNumberForCallFrame):
+ (JSC::Interpreter::getStackTrace):
+
+2012-02-26 Patrick Gansterer <paroga@webkit.org>
+
+ Unreviewed. Build fix for !ENABLE(JIT) after r108681.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::getLineNumberForCallFrame):
+
+2012-02-25 Filip Pizlo <fpizlo@apple.com>
+
+ LLInt assembly file should be split into 32-bit and 64-bit parts
+ https://bugs.webkit.org/show_bug.cgi?id=79584
+
+ Reviewed by Sam Weinig.
+
+ Moved LowLevelInterpreter.asm to LowLevelInterpreter32_64.asm. Gave offlineasm
+ the ability to include files, and correctly track dependencies: it restricts
+ the include mechanism to using the same directory as the source file, and uses
+ the SHA1 hash of all .asm files in that directory as an input hash.
+
+ * llint/LLIntOfflineAsmConfig.h:
+ * llint/LowLevelInterpreter.asm:
+ * llint/LowLevelInterpreter32_64.asm: Added.
+ - This is just the entire contents of what was previously LowLevelInterpreter.asm
+ * llint/LowLevelInterpreter64.asm: Added.
+ * offlineasm/asm.rb:
+ * offlineasm/ast.rb:
+ * offlineasm/generate_offset_extractor.rb:
+ * offlineasm/parser.rb:
+ * offlineasm/self_hash.rb:
+
+2012-02-25 Filip Pizlo <fpizlo@apple.com>
+
+ Offlineasm should support X86_64
+ https://bugs.webkit.org/show_bug.cgi?id=79581
+
+ Reviewed by Oliver Hunt.
+
+ * llint/LLIntOfflineAsmConfig.h:
+ * offlineasm/backends.rb:
+ * offlineasm/instructions.rb:
+ * offlineasm/settings.rb:
+ * offlineasm/x86.rb:
+
+2012-02-25 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should support activations and nested functions
+ https://bugs.webkit.org/show_bug.cgi?id=79554
+
+ Reviewed by Oliver Hunt.
+
+ Wrote the simplest possible implementation of activations. Big speed-up on
+ code that uses activations, no speed-up on major benchmarks (SunSpider, V8,
+ Kraken) because they do not appear to have sufficient coverage over code
+ that uses activations.
+
+ * bytecode/PredictedType.cpp:
+ (JSC::predictionToString):
+ (JSC::predictionFromValue):
+ * bytecode/PredictedType.h:
+ (JSC):
+ (JSC::isEmptyPrediction):
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::ByteCodeParser):
+ (ByteCodeParser):
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ (JSC::DFG::ByteCodeParser::buildOperandMapsIfNecessary):
+ (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+ (JSC::DFG::ByteCodeParser::parse):
+ * dfg/DFGCapabilities.h:
+ (JSC::DFG::canCompileOpcode):
+ (JSC::DFG::canInlineOpcode):
+ * dfg/DFGGraph.h:
+ (JSC::DFG::Graph::needsActivation):
+ * dfg/DFGNode.h:
+ (DFG):
+ (JSC::DFG::Node::storageAccessDataIndex):
+ (Node):
+ (JSC::DFG::Node::hasFunctionDeclIndex):
+ (JSC::DFG::Node::functionDeclIndex):
+ (JSC::DFG::Node::hasFunctionExprIndex):
+ (JSC::DFG::Node::functionExprIndex):
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileNewFunctionNoCheck):
+ (DFG):
+ (JSC::DFG::SpeculativeJIT::compileNewFunctionExpression):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::callOperation):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2012-02-25 Benjamin Poulain <benjamin@webkit.org>
+
+ Add an empty skeleton of KURL for WTFURL
+ https://bugs.webkit.org/show_bug.cgi?id=78990
+
+ Reviewed by Adam Barth.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj: Export the relevant classes from WTFURL
+ so that can use them in WebCore.
+
+2012-02-25 Filip Pizlo <fpizlo@apple.com>
+
+ Unreviewed, fix build for DFG disabled and LLInt enabled.
+
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompile):
+ * llint/LLIntSlowPaths.cpp:
+ (LLInt):
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+
+2012-02-25 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Fix the CopiedBlock offset alignment in a cross platform fashion
+ https://bugs.webkit.org/show_bug.cgi?id=79556
+
+ Reviewed by Filip Pizlo.
+
+ Replaced m_payload with a payload() method that calculates the offset
+ of the payload with the proper alignment. This change allows us to
+ avoid alignment-related issues in a cross-platform manner.
+
+ * heap/CopiedAllocator.h:
+ (JSC::CopiedAllocator::currentUtilization):
+ * heap/CopiedBlock.h:
+ (JSC::CopiedBlock::CopiedBlock):
+ (JSC::CopiedBlock::payload):
+ (CopiedBlock):
+ * heap/CopiedSpace.cpp:
+ (JSC::CopiedSpace::doneFillingBlock):
+ * heap/CopiedSpaceInlineMethods.h:
+ (JSC::CopiedSpace::borrowBlock):
+ (JSC::CopiedSpace::allocateFromBlock):
+
+2012-02-24 Michael Saboff <msaboff@apple.com>
+
+ Unreviewed, Windows build fix. Changed signature in export to match
+ change made in r108858.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2012-02-24 Filip Pizlo <fpizlo@apple.com>
+
+ DFG support for op_new_regexp should be enabled
+ https://bugs.webkit.org/show_bug.cgi?id=79538
+
+ Reviewed by Oliver Hunt.
+
+ No performance change.
+
+ * dfg/DFGCapabilities.h:
+ (JSC::DFG::canCompileOpcode):
+ * dfg/DFGCommon.h:
+
+2012-02-24 Michael Saboff <msaboff@apple.com>
+
+ ASSERT(position < 0) in JSC::Yarr::Interpreter::InputStream::readChecked
+ https://bugs.webkit.org/show_bug.cgi?id=73728
+
+ Reviewed by Gavin Barraclough.
+
+ Fixed the mixing of signed and unsigned character indeces in YARR
+ interpreter.
+
+ * runtime/RegExp.cpp:
+ (JSC::RegExp::match): Added code to check for match longer than 2^31 and
+ return no match after resetting the offsets.
+ * yarr/YarrInterpreter.cpp: Changed to use unsigned for all character index
+ handling except when matching back references.
+ (JSC::Yarr::Interpreter::InputStream::readChecked):
+ (JSC::Yarr::Interpreter::InputStream::checkInput):
+ (JSC::Yarr::Interpreter::InputStream::uncheckInput):
+ (JSC::Yarr::Interpreter::InputStream::atStart):
+ (JSC::Yarr::Interpreter::InputStream::atEnd):
+ (JSC::Yarr::Interpreter::InputStream::isAvailableInput):
+ (JSC::Yarr::Interpreter::checkCharacter):
+ (JSC::Yarr::Interpreter::checkCasedCharacter):
+ (JSC::Yarr::Interpreter::checkCharacterClass):
+ (JSC::Yarr::Interpreter::tryConsumeBackReference):
+ (JSC::Yarr::Interpreter::matchAssertionBOL):
+ (JSC::Yarr::Interpreter::matchAssertionWordBoundary):
+ (JSC::Yarr::Interpreter::backtrackPatternCharacter):
+ (JSC::Yarr::Interpreter::backtrackPatternCasedCharacter):
+ (JSC::Yarr::Interpreter::matchCharacterClass):
+ (JSC::Yarr::Interpreter::backtrackCharacterClass):
+ (JSC::Yarr::Interpreter::matchParenthesesOnceBegin):
+ (JSC::Yarr::Interpreter::matchDisjunction):
+ (JSC::Yarr::Interpreter::interpret):
+ (JSC::Yarr::ByteCompiler::assertionBOL):
+ (JSC::Yarr::ByteCompiler::assertionEOL):
+ (JSC::Yarr::ByteCompiler::assertionWordBoundary):
+ (JSC::Yarr::ByteCompiler::atomPatternCharacter):
+ (JSC::Yarr::ByteCompiler::atomCharacterClass):
+ (JSC::Yarr::ByteCompiler::atomBackReference):
+ (JSC::Yarr::ByteCompiler::atomParenthesesOnceBegin):
+ (JSC::Yarr::ByteCompiler::atomParenthesesTerminalBegin):
+ (JSC::Yarr::ByteCompiler::atomParenthesesSubpatternBegin):
+ (JSC::Yarr::ByteCompiler::atomParentheticalAssertionEnd):
+ (JSC::Yarr::ByteCompiler::emitDisjunction):
+ * yarr/YarrInterpreter.h:
+
+2012-02-24 Filip Pizlo <fpizlo@apple.com>
+
+ Unreviewed, build fix for builds where the DFG is disabled but the LLInt is
+ enabled.
+
+ * llint/LLIntOfflineAsmConfig.h:
+ * llint/LowLevelInterpreter.asm:
+
+2012-02-24 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should be able to handle variables getting captured
+ https://bugs.webkit.org/show_bug.cgi?id=79469
+
+ Reviewed by Oliver Hunt.
+
+ Made captured variables work by placing a Flush on the SetLocal and
+ forcing the emission of the GetLocal even if copy propagation tells us
+ who has the value.
+
+ Changed the CFA and various prediction codes to understand that we can't
+ really prove anything about captured variables. Well, we could in the
+ future by just looking at what side effects are happening, but in this
+ first cut we just assume that we can't reason about captured variables.
+
+ Also added a mode where the DFG pretends that all variables and arguments
+ got captured. Used this mode to harden the code.
+
+ This is performance neutral. Capturing all variables is a slow down, but
+ not too big of one. This seems to predict that when we add activation
+ support, the amount of speed benefit we'll get from increased coverage
+ will far outweigh the pessimism that we'll have to endure for captured
+ variables.
+
+ * bytecode/CodeType.h:
+ (JSC::codeTypeToString):
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::initialize):
+ (JSC::DFG::AbstractState::endBasicBlock):
+ (JSC::DFG::AbstractState::execute):
+ (JSC::DFG::AbstractState::merge):
+ * dfg/DFGAbstractState.h:
+ (AbstractState):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::getLocal):
+ (JSC::DFG::ByteCodeParser::setLocal):
+ (JSC::DFG::ByteCodeParser::getArgument):
+ (JSC::DFG::ByteCodeParser::setArgument):
+ (JSC::DFG::ByteCodeParser::flushArgument):
+ (JSC::DFG::ByteCodeParser::handleInlining):
+ (JSC::DFG::ByteCodeParser::processPhiStack):
+ (JSC::DFG::ByteCodeParser::parseCodeBlock):
+ (JSC::DFG::ByteCodeParser::parse):
+ * dfg/DFGCapabilities.h:
+ (JSC::DFG::mightInlineFunctionForCall):
+ (JSC::DFG::mightInlineFunctionForConstruct):
+ * dfg/DFGCommon.h:
+ * dfg/DFGGraph.h:
+ (JSC::DFG::Graph::needsActivation):
+ (Graph):
+ (JSC::DFG::Graph::argumentIsCaptured):
+ (JSC::DFG::Graph::localIsCaptured):
+ (JSC::DFG::Graph::isCaptured):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::shouldGenerate):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (DFG):
+ (JSC::DFG::ValueSource::dump):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT.h:
+ (ValueSource):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGVirtualRegisterAllocationPhase.cpp:
+ (JSC::DFG::VirtualRegisterAllocationPhase::run):
+
+2012-02-24 Gavin Barraclough <barraclough@apple.com>
+
+ Should not allow malformed \x escapes
+ https://bugs.webkit.org/show_bug.cgi?id=79462
+
+ Reviewed by Oliver Hunt.
+
+ * parser/Lexer.cpp:
+ (JSC::::parseString):
+ (JSC::::parseStringSlowCase):
+ - Prohibit malformed '\x' escapes
+ * tests/mozilla/ecma/Array/15.4.5.1-1.js:
+ * tests/mozilla/ecma/LexicalConventions/7.7.4.js:
+ * tests/mozilla/ecma_2/RegExp/hex-001.js:
+ * tests/mozilla/js1_2/regexp/hexadecimal.js:
+ - Remove erroneous test cases (correct behaviour is tested by LayoutTests/sputnik).
+
+2012-02-24 Daniel Bates <dbates@webkit.org>
+
+ Fix change log entry for changeset r108819; add bug URL
+ https://bugs.webkit.org/show_bug.cgi?id=79504
+
+ Changeset r108819 is associated with bug #79504.
+
+ * ChangeLog
+
+2012-02-24 Daniel Bates <dbates@webkit.org>
+
+ Substitute ENABLE(CLASSIC_INTERPRETER) for ENABLE(INTERPRETER) in Interpreter.cpp
+ https://bugs.webkit.org/show_bug.cgi?id=79504
+
+ Reviewed by Oliver Hunt.
+
+ There are a few places in Interpreter.cpp that need to be updated to use
+ ENABLE(CLASSIC_INTERPRETER) following the renaming of ENABLE_INTERPRETER to
+ ENABLE_CLASSIC_INTERPRETER in changeset <http://trac.webkit.org/changeset/108020>
+ (https://bugs.webkit.org/show_bug.cgi?id=78791).
+
+ * interpreter/Interpreter.cpp:
+ (JSC::getLineNumberForCallFrame):
+ (JSC::getCallerInfo):
+ (JSC::getSourceURLFromCallFrame):
+
+2012-02-24 Adam Roben <aroben@apple.com>
+
+ Undo the BUILDING_WTF part of r108808
+
+ This broke the build, which is obviously worse than the linker warning it was trying to
+ solve.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops:
+
+2012-02-24 Adam Roben <aroben@apple.com>
+
+ Fix linker warnings on Windows
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: Removed symbols that are already
+ exported via JS_EXPORTDATA.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops: Define BUILDING_WTF. We
+ aren't actually building WTF, but we are statically linking it, so we need to define this
+ symbol so that we export WTF's exports.
+
+2012-02-24 Philippe Normand <pnormand@igalia.com>
+
+ Fix GTK WebAudio build for WebKitGTK 1.7.90.
+
+ Patch by Priit Laes <plaes@plaes.org> on 2012-02-24
+ Rubber-stamped by Philippe Normand.
+
+ * GNUmakefile.list.am: Add Complex.h to the list of files so it
+ gets disted in the tarballs.
+
2012-02-24 Zoltan Herczeg <zherczeg@webkit.org>
[Qt] Buildfix for "Zero out CopiedBlocks on initialization".
diff --git a/Source/JavaScriptCore/Configurations/Base.xcconfig b/Source/JavaScriptCore/Configurations/Base.xcconfig
index 40c11b647..e4d3617fd 100644
--- a/Source/JavaScriptCore/Configurations/Base.xcconfig
+++ b/Source/JavaScriptCore/Configurations/Base.xcconfig
@@ -71,7 +71,7 @@ WARNING_CFLAGS_macosx_ppc = $(WARNING_CFLAGS_BASE) -Wshorten-64-to-32;
// FIXME: JavaScriptCore 64-bit builds should build with -Wshorten-64-to-32
WARNING_CFLAGS_macosx_ppc64 = $(WARNING_CFLAGS_BASE);
WARNING_CFLAGS_macosx_x86_64 = $(WARNING_CFLAGS_BASE);
-HEADER_SEARCH_PATHS = . icu $(HEADER_SEARCH_PATHS);
+HEADER_SEARCH_PATHS = . icu "${BUILT_PRODUCTS_DIR}/usr/local/include" $(HEADER_SEARCH_PATHS);
CLANG_CXX_LIBRARY = $(CLANG_CXX_LIBRARY_$(TARGET_MAC_OS_X_VERSION_MAJOR));
CLANG_CXX_LIBRARY_1060 = libstdc++;
@@ -87,6 +87,11 @@ REAL_PLATFORM_NAME_macosx = macosx;
TARGET_MAC_OS_X_VERSION_MAJOR = $(MAC_OS_X_VERSION_MAJOR);
+FRAMEWORK_SEARCH_PATHS = $(STAGED_FRAMEWORKS_SEARCH_PATH);
+
+STAGED_FRAMEWORKS_SEARCH_PATH = $(STAGED_FRAMEWORKS_SEARCH_PATH_$(USE_STAGING_INSTALL_PATH));
+STAGED_FRAMEWORKS_SEARCH_PATH_YES = $(NEXT_ROOT)$(SYSTEM_LIBRARY_DIR)/StagedFrameworks/Safari;
+
NORMAL_JAVASCRIPTCORE_FRAMEWORKS_DIR = $(NORMAL_JAVASCRIPTCORE_FRAMEWORKS_DIR_$(REAL_PLATFORM_NAME));
NORMAL_JAVASCRIPTCORE_FRAMEWORKS_DIR_iphoneos = $(SYSTEM_LIBRARY_DIR)/PrivateFrameworks;
NORMAL_JAVASCRIPTCORE_FRAMEWORKS_DIR_iphonesimulator = $(NORMAL_JAVASCRIPTCORE_FRAMEWORKS_DIR_iphoneos);
diff --git a/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig b/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig
index 576e746ad..58a02f521 100644
--- a/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig
+++ b/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig
@@ -90,12 +90,14 @@ ENABLE_INDEXED_DATABASE = ;
ENABLE_INPUT_COLOR = ;
ENABLE_INPUT_SPEECH = ;
ENABLE_JAVASCRIPT_DEBUGGER = ENABLE_JAVASCRIPT_DEBUGGER;
+ENABLE_LEGACY_NOTIFICATIONS = ENABLE_LEGACY_NOTIFICATIONS;
ENABLE_LINK_PREFETCH = ;
ENABLE_MATHML = ENABLE_MATHML;
ENABLE_MEDIA_SOURCE = ;
ENABLE_MEDIA_STATISTICS = ;
ENABLE_METER_TAG = ENABLE_METER_TAG;
ENABLE_MHTML = ;
+ENABLE_MICRODATA = ;
ENABLE_MUTATION_OBSERVERS = ENABLE_MUTATION_OBSERVERS;
ENABLE_NOTIFICATIONS = $(ENABLE_NOTIFICATIONS_$(REAL_PLATFORM_NAME));
@@ -109,6 +111,7 @@ ENABLE_PROGRESS_TAG = ENABLE_PROGRESS_TAG;
ENABLE_QUOTA = ;
ENABLE_REGISTER_PROTOCOL_HANDLER = ;
ENABLE_REQUEST_ANIMATION_FRAME = ENABLE_REQUEST_ANIMATION_FRAME;
+ENABLE_SCRIPTED_SPEECH = ;
ENABLE_SHADOW_DOM = ;
ENABLE_SHARED_WORKERS = ENABLE_SHARED_WORKERS;
ENABLE_SQL_DATABASE = ENABLE_SQL_DATABASE;
@@ -118,7 +121,10 @@ ENABLE_SVG_FONTS = ENABLE_SVG_FONTS;
ENABLE_TEXT_NOTIFICATIONS_ONLY = ENABLE_TEXT_NOTIFICATIONS_ONLY;
ENABLE_TOUCH_ICON_LOADING = ;
ENABLE_VIDEO = ENABLE_VIDEO;
-ENABLE_VIDEO_TRACK = ;
+
+ENABLE_VIDEO_TRACK = $(ENABLE_VIDEO_TRACK_$(REAL_PLATFORM_NAME));
+ENABLE_VIDEO_TRACK_macosx = ENABLE_VIDEO_TRACK;
+
ENABLE_WEBGL = ENABLE_WEBGL;
ENABLE_WEB_AUDIO = ENABLE_WEB_AUDIO;
ENABLE_WEB_SOCKETS = ENABLE_WEB_SOCKETS;
@@ -126,4 +132,4 @@ ENABLE_WEB_TIMING = ;
ENABLE_WORKERS = ENABLE_WORKERS;
ENABLE_XSLT = ENABLE_XSLT;
-FEATURE_DEFINES = $(ENABLE_3D_RENDERING) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ANIMATION_API) $(ENABLE_BLOB) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CLIENT_BASED_GEOLOCATION) $(ENABLE_CSS_FILTERS) $(ENABLE_CSS_GRID_LAYOUT) $(ENABLE_CSS_SHADERS) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATALIST) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DIRECTORY_UPLOAD) $(ENABLE_FILE_SYSTEM) $(ENABLE_FILTERS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_COLOR) $(ENABLE_INPUT_SPEECH) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_LINK_PREFETCH) $(ENABLE_MATHML) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_METER_TAG) $(ENABLE_MUTATION_OBSERVERS) $(ENABLE_NOTIFICATIONS) $(ENABLE_PAGE_VISIBILITY_API) $(ENABLE_PROGRESS_TAG) $(ENABLE_QUOTA) $(ENABLE_REGISTER_PROTOCOL_HANDLER) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_SHADOW_DOM) $(ENABLE_SHARED_WORKERS) $(ENABLE_SQL_DATABASE) $(ENABLE_STYLE_SCOPED) $(ENABLE_SVG) $(ENABLE_SVG_DOM_OBJC_BINDINGS) $(ENABLE_SVG_FONTS) $(ENABLE_TEXT_NOTIFICATIONS_ONLY) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_WEBGL) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WORKERS) $(ENABLE_XSLT);
+FEATURE_DEFINES = $(ENABLE_3D_RENDERING) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ANIMATION_API) $(ENABLE_BLOB) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CLIENT_BASED_GEOLOCATION) $(ENABLE_CSS_FILTERS) $(ENABLE_CSS_GRID_LAYOUT) $(ENABLE_CSS_SHADERS) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATALIST) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DIRECTORY_UPLOAD) $(ENABLE_FILE_SYSTEM) $(ENABLE_FILTERS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_COLOR) $(ENABLE_INPUT_SPEECH) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LINK_PREFETCH) $(ENABLE_MATHML) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_METER_TAG) $(ENABLE_MICRODATA) $(ENABLE_MUTATION_OBSERVERS) $(ENABLE_NOTIFICATIONS) $(ENABLE_PAGE_VISIBILITY_API) $(ENABLE_PROGRESS_TAG) $(ENABLE_QUOTA) $(ENABLE_REGISTER_PROTOCOL_HANDLER) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_SCRIPTED_SPEECH) $(ENABLE_SHADOW_DOM) $(ENABLE_SHARED_WORKERS) $(ENABLE_SQL_DATABASE) $(ENABLE_STYLE_SCOPED) $(ENABLE_SVG) $(ENABLE_SVG_DOM_OBJC_BINDINGS) $(ENABLE_SVG_FONTS) $(ENABLE_TEXT_NOTIFICATIONS_ONLY) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_WEBGL) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WORKERS) $(ENABLE_XSLT);
diff --git a/Source/JavaScriptCore/Configurations/JavaScriptCore.xcconfig b/Source/JavaScriptCore/Configurations/JavaScriptCore.xcconfig
index d88b46e4e..fcef7550c 100644
--- a/Source/JavaScriptCore/Configurations/JavaScriptCore.xcconfig
+++ b/Source/JavaScriptCore/Configurations/JavaScriptCore.xcconfig
@@ -50,3 +50,5 @@ INFOPLIST_FILE = Info.plist;
INSTALL_PATH = $(JAVASCRIPTCORE_FRAMEWORKS_DIR);
DYLIB_INSTALL_NAME_BASE = $(NORMAL_JAVASCRIPTCORE_FRAMEWORKS_DIR);
PRODUCT_NAME = JavaScriptCore;
+
+INSTALLHDRS_SCRIPT_PHASE = YES;
diff --git a/Source/JavaScriptCore/Configurations/TestRegExp.xcconfig b/Source/JavaScriptCore/Configurations/TestRegExp.xcconfig
deleted file mode 100644
index 963ec34b3..000000000
--- a/Source/JavaScriptCore/Configurations/TestRegExp.xcconfig
+++ /dev/null
@@ -1,30 +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.
-
-INSTALL_PATH = $(JAVASCRIPTCORE_FRAMEWORKS_DIR)/JavaScriptCore.framework/Resources
-PRODUCT_NAME = testRegExp;
-
-SKIP_INSTALL = $(SKIP_INSTALL_$(FORCE_TOOL_INSTALL));
-SKIP_INSTALL_ = YES;
-SKIP_INSTALL_NO = YES;
-SKIP_INSTALL_YES = NO;
diff --git a/Source/JavaScriptCore/Configurations/TestAPI.xcconfig b/Source/JavaScriptCore/Configurations/ToolExecutable.xcconfig
index 65ac95ea0..194c240fa 100644
--- a/Source/JavaScriptCore/Configurations/TestAPI.xcconfig
+++ b/Source/JavaScriptCore/Configurations/ToolExecutable.xcconfig
@@ -22,7 +22,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
INSTALL_PATH = $(JAVASCRIPTCORE_FRAMEWORKS_DIR)/JavaScriptCore.framework/Resources
-PRODUCT_NAME = testapi;
+PRODUCT_NAME = $(TARGET_NAME);
SKIP_INSTALL = $(SKIP_INSTALL_$(FORCE_TOOL_INSTALL));
SKIP_INSTALL_ = YES;
diff --git a/Source/JavaScriptCore/Configurations/Version.xcconfig b/Source/JavaScriptCore/Configurations/Version.xcconfig
index 7e3f57ea8..7477f4b74 100644
--- a/Source/JavaScriptCore/Configurations/Version.xcconfig
+++ b/Source/JavaScriptCore/Configurations/Version.xcconfig
@@ -21,8 +21,8 @@
// (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 = 535;
-MINOR_VERSION = 23;
+MAJOR_VERSION = 536;
+MINOR_VERSION = 3;
TINY_VERSION = 0;
FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION);
diff --git a/Source/JavaScriptCore/GNUmakefile.list.am b/Source/JavaScriptCore/GNUmakefile.list.am
index 36b64a375..430b564c0 100644
--- a/Source/JavaScriptCore/GNUmakefile.list.am
+++ b/Source/JavaScriptCore/GNUmakefile.list.am
@@ -95,6 +95,8 @@ javascriptcore_sources += \
Source/JavaScriptCore/bytecode/DFGExitProfile.cpp \
Source/JavaScriptCore/bytecode/DFGExitProfile.h \
Source/JavaScriptCore/bytecode/EvalCodeCache.h \
+ Source/JavaScriptCore/bytecode/ExecutionCounter.cpp \
+ Source/JavaScriptCore/bytecode/ExecutionCounter.h \
Source/JavaScriptCore/bytecode/ExpressionRangeInfo.h \
Source/JavaScriptCore/bytecode/GetByIdStatus.cpp \
Source/JavaScriptCore/bytecode/GetByIdStatus.h \
@@ -167,6 +169,7 @@ javascriptcore_sources += \
Source/JavaScriptCore/dfg/DFGGraph.h \
Source/JavaScriptCore/dfg/DFGJITCompiler.cpp \
Source/JavaScriptCore/dfg/DFGJITCompiler.h \
+ Source/JavaScriptCore/dfg/DFGNode.cpp \
Source/JavaScriptCore/dfg/DFGNode.h \
Source/JavaScriptCore/dfg/DFGNodeReferenceBlob.h \
Source/JavaScriptCore/dfg/DFGNodeUse.h \
@@ -185,6 +188,8 @@ javascriptcore_sources += \
Source/JavaScriptCore/dfg/DFGPhase.h \
Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp \
Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.h \
+ Source/JavaScriptCore/dfg/DFGRedundantPhiEliminationPhase.cpp \
+ Source/JavaScriptCore/dfg/DFGRedundantPhiEliminationPhase.h \
Source/JavaScriptCore/dfg/DFGRegisterBank.h \
Source/JavaScriptCore/dfg/DFGRepatch.cpp \
Source/JavaScriptCore/dfg/DFGRepatch.h \
@@ -309,6 +314,7 @@ javascriptcore_sources += \
Source/JavaScriptCore/jit/JITCall32_64.cpp \
Source/JavaScriptCore/jit/JITCall.cpp \
Source/JavaScriptCore/jit/JITCode.h \
+ Source/JavaScriptCore/jit/JITCompilationEffort.h \
Source/JavaScriptCore/jit/JITDriver.h \
Source/JavaScriptCore/jit/JIT.cpp \
Source/JavaScriptCore/jit/JIT.h \
@@ -328,6 +334,10 @@ javascriptcore_sources += \
Source/JavaScriptCore/jit/ThunkGenerators.cpp \
Source/JavaScriptCore/jit/ThunkGenerators.h \
Source/JavaScriptCore/llint/LLIntData.h \
+ Source/JavaScriptCore/llint/LLIntEntrypoints.cpp \
+ Source/JavaScriptCore/llint/LLIntEntrypoints.h \
+ Source/JavaScriptCore/llint/LowLevelInterpreter.cpp \
+ Source/JavaScriptCore/llint/LowLevelInterpreter.h \
Source/JavaScriptCore/os-win32/stdbool.h \
Source/JavaScriptCore/os-win32/stdint.h \
Source/JavaScriptCore/parser/ASTBuilder.h \
@@ -583,7 +593,9 @@ javascriptcore_sources += \
Source/JavaScriptCore/wtf/ByteArray.h \
Source/JavaScriptCore/wtf/CheckedArithmetic.h \
Source/JavaScriptCore/wtf/CheckedBoolean.h \
+ Source/JavaScriptCore/wtf/RefCountedArray.h \
Source/JavaScriptCore/wtf/Compiler.h \
+ Source/JavaScriptCore/wtf/Complex.h \
Source/JavaScriptCore/wtf/CryptographicallyRandomNumber.cpp \
Source/JavaScriptCore/wtf/CryptographicallyRandomNumber.h \
Source/JavaScriptCore/wtf/CurrentTime.cpp \
@@ -710,6 +722,7 @@ javascriptcore_sources += \
Source/JavaScriptCore/wtf/SentinelLinkedList.h \
Source/JavaScriptCore/wtf/SHA1.cpp \
Source/JavaScriptCore/wtf/SHA1.h \
+ Source/JavaScriptCore/wtf/SimpleStats.h \
Source/JavaScriptCore/wtf/SinglyLinkedList.h \
Source/JavaScriptCore/wtf/Spectrum.h \
Source/JavaScriptCore/wtf/StackBounds.cpp \
@@ -831,4 +844,5 @@ Programs_minidom_SOURCES = \
Source/JavaScriptCore/API/tests/minidom.c
Programs_jsc_@WEBKITGTK_API_MAJOR_VERSION@_SOURCES = \
+ Source/JavaScriptCore/JSCTypedArrayStubs.h \
Source/JavaScriptCore/jsc.cpp
diff --git a/Source/JavaScriptCore/JSCTypedArrayStubs.h b/Source/JavaScriptCore/JSCTypedArrayStubs.h
index cda55fc9b..e3546ee65 100644
--- a/Source/JavaScriptCore/JSCTypedArrayStubs.h
+++ b/Source/JavaScriptCore/JSCTypedArrayStubs.h
@@ -151,7 +151,7 @@ void JS##name##Array::indexSetter(JSC::ExecState* exec, unsigned index, JSC::JSV
m_impl->set(index, value.toNumber(exec));\
}\
\
-void JS##name##Array::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue value)\
+void JS##name##Array::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue value, bool)\
{\
JS##name##Array* thisObject = jsCast<JS##name##Array*>(cell);\
ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info);\
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.sln b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.sln
index 009a8a044..0834a3fe8 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.sln
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.sln
@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JavaScriptCore", "JavaScriptCore\JavaScriptCore.vcproj", "{011D10F1-B656-4A1B-A0C3-3842F02122C5}"
ProjectSection(ProjectDependencies) = postProject
- {AA8A5A85-592B-4357-BC60-E0E91E026AF6} = {AA8A5A85-592B-4357-BC60-E0E91E026AF6}
+ {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A} = {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jsc", "jsc\jsc.vcproj", "{C59E5129-B453-49B7-A52B-1E104715F76E}"
@@ -13,16 +13,21 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jsc", "jsc\jsc.vcproj", "{C
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WTF", "WTF\WTF.vcproj", "{AA8A5A85-592B-4357-BC60-E0E91E026AF6}"
ProjectSection(ProjectDependencies) = postProject
- {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A} = {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}
+ {5AE5F5E4-782D-4F63-B4D7-3977B52B9950} = {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JavaScriptCoreGenerated", "JavaScriptCore\JavaScriptCoreGenerated.vcproj", "{4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}"
+ ProjectSection(ProjectDependencies) = postProject
+ {AA8A5A85-592B-4357-BC60-E0E91E026AF6} = {AA8A5A85-592B-4357-BC60-E0E91E026AF6}
+ EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testRegExp", "testRegExp\testRegExp.vcproj", "{14C94979-1ED3-4E1D-9B55-A80FCF4677D0}"
ProjectSection(ProjectDependencies) = postProject
{C59E5129-B453-49B7-A52B-1E104715F76E} = {C59E5129-B453-49B7-A52B-1E104715F76E}
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WTFGenerated", "WTF\WTFGenerated.vcproj", "{5AE5F5E4-782D-4F63-B4D7-3977B52B9950}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug_All|Win32 = Debug_All|Win32
@@ -77,10 +82,10 @@ Global
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Production|Win32.Build.0 = Production|Win32
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release_Cairo_CFLite|Win32.ActiveCfg = Release_Cairo_CFLite|Win32
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release_Cairo_CFLite|Win32.Build.0 = Release_Cairo_CFLite|Win32
- {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release_PGO_Optimize|Win32.ActiveCfg = Release_PGO|Win32
- {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release_PGO_Optimize|Win32.Build.0 = Release_PGO|Win32
- {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release_PGO|Win32.ActiveCfg = Release_PGO|Win32
- {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release_PGO|Win32.Build.0 = Release_PGO|Win32
+ {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release_PGO_Optimize|Win32.ActiveCfg = Production|Win32
+ {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release_PGO_Optimize|Win32.Build.0 = Production|Win32
+ {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release_PGO|Win32.ActiveCfg = Production|Win32
+ {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release_PGO|Win32.Build.0 = Production|Win32
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release|Win32.ActiveCfg = Release|Win32
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release|Win32.Build.0 = Release|Win32
{4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Debug_All|Win32.ActiveCfg = Debug_All|Win32
@@ -115,6 +120,22 @@ Global
{14C94979-1ED3-4E1D-9B55-A80FCF4677D0}.Release_PGO|Win32.Build.0 = Release_PGO|Win32
{14C94979-1ED3-4E1D-9B55-A80FCF4677D0}.Release|Win32.ActiveCfg = Release|Win32
{14C94979-1ED3-4E1D-9B55-A80FCF4677D0}.Release|Win32.Build.0 = Release|Win32
+ {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}.Debug_All|Win32.ActiveCfg = Debug_All|Win32
+ {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}.Debug_All|Win32.Build.0 = Debug_All|Win32
+ {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}.Debug_Cairo_CFLite|Win32.ActiveCfg = Debug_Cairo_CFLite|Win32
+ {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}.Debug_Cairo_CFLite|Win32.Build.0 = Debug_Cairo_CFLite|Win32
+ {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}.Debug|Win32.ActiveCfg = Debug|Win32
+ {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}.Debug|Win32.Build.0 = Debug|Win32
+ {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}.Production|Win32.ActiveCfg = Production|Win32
+ {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}.Production|Win32.Build.0 = Production|Win32
+ {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}.Release_Cairo_CFLite|Win32.ActiveCfg = Release_Cairo_CFLite|Win32
+ {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}.Release_Cairo_CFLite|Win32.Build.0 = Release_Cairo_CFLite|Win32
+ {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}.Release_PGO_Optimize|Win32.ActiveCfg = Production|Win32
+ {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}.Release_PGO_Optimize|Win32.Build.0 = Production|Win32
+ {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}.Release_PGO|Win32.ActiveCfg = Production|Win32
+ {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}.Release_PGO|Win32.Build.0 = Production|Win32
+ {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}.Release|Win32.ActiveCfg = Release|Win32
+ {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
index acdf47b7c..c50a4252b 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
@@ -137,7 +137,6 @@ EXPORTS
?dayInMonthFromDayInYear@WTF@@YAHH_N@Z
?dayInYear@WTF@@YAHNH@Z
?decrement@RefCountedLeakCounter@WTF@@QAEXXZ
- ?defaultAttributes@PropertyDescriptor@JSC@@0IA
?defaultValue@JSObject@JSC@@SA?AVJSValue@2@PBV12@PAVExecState@2@W4PreferredPrimitiveType@2@@Z
?defineOwnProperty@JSGlobalObject@JSC@@SA_NPAVJSObject@2@PAVExecState@2@ABVIdentifier@2@AAVPropertyDescriptor@2@_N@Z
?defineOwnProperty@JSObject@JSC@@SA_NPAV12@PAVExecState@2@ABVIdentifier@2@AAVPropertyDescriptor@2@_N@Z
@@ -230,7 +229,7 @@ EXPORTS
?initializeMainThread@WTF@@YAXXZ
?initializeThreading@JSC@@YAXXZ
?initializeThreading@WTF@@YAXXZ
- ?interpret@Yarr@JSC@@YAHPAUBytecodePattern@12@ABVUString@2@IIPAH@Z
+ ?interpret@Yarr@JSC@@YAIPAUBytecodePattern@12@ABVUString@2@IIPAI@Z
?isAccessorDescriptor@PropertyDescriptor@JSC@@QBE_NXZ
?isBusy@Heap@JSC@@QAE_NXZ
?isDataDescriptor@PropertyDescriptor@JSC@@QBE_NXZ
@@ -276,8 +275,8 @@ EXPORTS
?put@JSByteArray@JSC@@SAXPAVJSCell@2@PAVExecState@2@ABVIdentifier@2@VJSValue@2@AAVPutPropertySlot@2@@Z
?put@JSGlobalObject@JSC@@SAXPAVJSCell@2@PAVExecState@2@ABVIdentifier@2@VJSValue@2@AAVPutPropertySlot@2@@Z
?put@JSObject@JSC@@SAXPAVJSCell@2@PAVExecState@2@ABVIdentifier@2@VJSValue@2@AAVPutPropertySlot@2@@Z
- ?putByIndex@JSByteArray@JSC@@SAXPAVJSCell@2@PAVExecState@2@IVJSValue@2@@Z
- ?putByIndex@JSObject@JSC@@SAXPAVJSCell@2@PAVExecState@2@IVJSValue@2@@Z
+ ?putByIndex@JSObject@JSC@@SAXPAVJSCell@2@PAVExecState@2@IVJSValue@2@_N@Z
+ ?putDirectIndexBeyondVectorLength@JSArray@JSC@@AAE_NPAVExecState@2@IVJSValue@2@_N@Z
?putDirectVirtual@JSGlobalObject@JSC@@SAXPAVJSObject@2@PAVExecState@2@ABVIdentifier@2@VJSValue@2@I@Z
?putDirectVirtual@JSObject@JSC@@SAXPAV12@PAVExecState@2@ABVIdentifier@2@VJSValue@2@I@Z
?randomNumber@WTF@@YANXZ
@@ -298,7 +297,6 @@ EXPORTS
?restoreAll@Profile@JSC@@QAEXXZ
?retrieveCallerFromVMCode@Interpreter@JSC@@QBE?AVJSValue@2@PAVExecState@2@PAVJSFunction@2@@Z
?retrieveLastCaller@Interpreter@JSC@@QBEXPAVExecState@2@AAH1AAVUString@2@AAVJSValue@2@@Z
- ?s_globalObjectMethodTable@JSGlobalObject@JSC@@1UGlobalObjectMethodTable@2@B
?setConfigurable@PropertyDescriptor@JSC@@QAEX_N@Z
?setDescriptor@PropertyDescriptor@JSC@@QAEXVJSValue@2@I@Z
?setDumpsGeneratedCode@BytecodeGenerator@JSC@@SAX_N@Z
@@ -350,6 +348,7 @@ EXPORTS
?toThisObject@JSObject@JSC@@SAPAV12@PAVJSCell@2@PAVExecState@2@@Z
?toThisObjectSlowCase@JSValue@JSC@@ABEPAVJSObject@2@PAVExecState@2@@Z
?toUInt32@Identifier@JSC@@SAIABVUString@2@AA_N@Z
+ ?transfer@ArrayBuffer@WTF@@QAE_NAAVArrayBufferContents@2@AAV?$Vector@V?$RefPtr@VArrayBufferView@WTF@@@WTF@@$0A@@2@@Z
?tryFastCalloc@WTF@@YA?AUTryMallocReturnValue@1@II@Z
?tryFastMalloc@WTF@@YA?AUTryMallocReturnValue@1@I@Z
?tryFastRealloc@WTF@@YA?AUTryMallocReturnValue@1@PAXI@Z
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
index b9e0f3152..8599dedb8 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
@@ -1478,6 +1478,10 @@
Name="bytecode"
>
<File
+ RelativePath="..\..\bytecode\ExecutionCounter.cpp"
+ >
+ </File>
+ <File
RelativePath="..\..\bytecode\MethodOfGettingAValueProfile.cpp"
>
</File>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make
index 20a9a5078..c7c640b0d 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make
@@ -1,9 +1,6 @@
all:
touch "%ConfigurationBuildDir%\buildfailed"
bash build-generated-files.sh "%ConfigurationBuildDir%" "$(WEBKITLIBRARIESDIR)"
-!IF "$(OFFICIAL_BUILD)"!="1"
- bash -c "python work-around-vs-dependency-tracking-bugs.py"
-!ENDIF
copy-files.cmd
-del "%ConfigurationBuildDir%\include\private\JavaScriptCore\stdbool.h" "%ConfigurationBuildDir%\include\private\JavaScriptCore\stdint.h"
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.vcproj b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.vcproj
index 6d3351ee1..5e91b148b 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.vcproj
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.vcproj
@@ -69,15 +69,6 @@
Name="VCNMakeTool"
/>
</Configuration>
- <Configuration
- Name="Release_PGO|Win32"
- ConfigurationType="0"
- InheritedPropertySheets=".\JavaScriptCoreGeneratedReleasePGO.vsprops"
- >
- <Tool
- Name="VCNMakeTool"
- />
- </Configuration>
</Configurations>
<References>
</References>
@@ -98,10 +89,6 @@
RelativePath=".\JavaScriptCoreGenerated.make"
>
</File>
- <File
- RelativePath=".\work-around-vs-dependency-tracking-bugs.py"
- >
- </File>
</Files>
<Globals>
</Globals>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/build-generated-files.sh b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/build-generated-files.sh
index 3998c65f9..56316e9d7 100755
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/build-generated-files.sh
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/build-generated-files.sh
@@ -1,15 +1,5 @@
#!/usr/bin/bash
-# Determine whether we have the versioned ICU 4.0 or the unversioned ICU 4.4
-UNVERSIONED_ICU_LIB_PATH=$(cygpath -u "${WEBKITLIBRARIESDIR}/lib/libicuuc.lib")
-ICUVERSION_H_PATH=$(cygpath -u "${CONFIGURATIONBUILDDIR}/include/private/ICUVersion.h")
-if test \( ! -f "${ICUVERSION_H_PATH}" \) -o \( -f "${UNVERSIONED_ICU_LIB_PATH}" -a \( "${UNVERSIONED_ICU_LIB_PATH}" -nt "${ICUVERSION_H_PATH}" \) \)
-then
- mkdir -p "$(dirname "${ICUVERSION_H_PATH}")"
- test ! -f "${UNVERSIONED_ICU_LIB_PATH}"
- echo "#define U_DISABLE_RENAMING $?" > "${ICUVERSION_H_PATH}"
-fi
-
NUMCPUS=`../../../../Tools/Scripts/num-cpus`
XSRCROOT="`pwd`/../.."
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/copy-files.cmd b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/copy-files.cmd
index 2c0cfad02..524e38037 100755
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/copy-files.cmd
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/copy-files.cmd
@@ -1,83 +1,66 @@
-@echo off
-
-set PublicHeadersDirectory=%CONFIGURATIONBUILDDIR%\include\JavaScriptCore
-set PrivateHeadersDirectory=%CONFIGURATIONBUILDDIR%\include\private\JavaScriptCore
-set ResourcesDirectory=%CONFIGURATIONBUILDDIR%\bin\JavaScriptCore.resources
-
-if "%1" EQU "clean" goto :clean
-if "%1" EQU "rebuild" call :clean
-
-echo Copying public headers...
-mkdir "%PublicHeadersDirectory%" 2>NUL
-for %%f in (
- APICast.h
- APIShims.h
- JSBase.h
- JSContextRef.h
- JSContextRefPrivate.h
- JSObjectRef.h
- JSObjectRefPrivate.h
- JSRetainPtr.h
- JSRetainPtr.h
- JSStringRef.h
- JSStringRefBSTR.h
- JSStringRefCF.h
- JSValueRef.h
- JSWeakObjectMapRefInternal.h
- JSWeakObjectMapRefPrivate.h
- JavaScript.h
- JavaScriptCore.h
- OpaqueJSString.h
- WebKitAvailability.h
-) do (
- xcopy /y /d ..\..\API\%%f "%PublicHeadersDirectory%" >NUL
-)
-
-echo Copying private headers...
-mkdir "%PrivateHeadersDirectory%" 2>NUL
-for %%d in (
- assembler
- bytecode
- dfg
- heap
- debugger
- interpreter
- jit
- llint
- parser
- profiler
- runtime
- wtf
- wtf\dtoa
- wtf\text
- wtf\threads
- wtf\unicode
- wtf\unicode\icu
- yarr
-) do (
- xcopy /y /d ..\..\%%d\*.h "%PrivateHeadersDirectory%" >NUL
-)
-
-echo Copying resources...
-mkdir "%ResourcesDirectory%" 2>NUL
-xcopy /y /d ..\JavaScriptCore.resources\* "%ResourcesDirectory%" >NUL
-
-echo Copying other files...
-for %%f in (
- create_hash_table
- wtf\text\AtomicString.cpp
- wtf\text\StringBuilder.cpp
- wtf\text\StringImpl.cpp
- wtf\text\WTFString.cpp
-) do (
- xcopy /y /d ..\..\%%f "%PrivateHeadersDirectory%" >NUL
-)
-
-goto :EOF
-
-:clean
-
-echo Deleting copied files...
-if exist "%PublicHeadersDirectory%" rmdir /s /q "%PublicHeadersDirectory%" >NUL
-if exist "%PrivateHeadersDirectory%" rmdir /s /q "%PrivateHeadersDirectory%" >NUL
-if exist "%ResourcesDirectory%" rmdir /s /q "%ResourcesDirectory%" >NUL
+@echo off
+
+set PublicHeadersDirectory=%CONFIGURATIONBUILDDIR%\include\JavaScriptCore
+set PrivateHeadersDirectory=%CONFIGURATIONBUILDDIR%\include\private\JavaScriptCore
+set ResourcesDirectory=%CONFIGURATIONBUILDDIR%\bin\JavaScriptCore.resources
+
+if "%1" EQU "clean" goto :clean
+if "%1" EQU "rebuild" call :clean
+
+echo Copying public headers...
+mkdir "%PublicHeadersDirectory%" 2>NUL
+for %%f in (
+ APICast.h
+ APIShims.h
+ JSBase.h
+ JSContextRef.h
+ JSContextRefPrivate.h
+ JSObjectRef.h
+ JSObjectRefPrivate.h
+ JSRetainPtr.h
+ JSRetainPtr.h
+ JSStringRef.h
+ JSStringRefBSTR.h
+ JSStringRefCF.h
+ JSValueRef.h
+ JSWeakObjectMapRefInternal.h
+ JSWeakObjectMapRefPrivate.h
+ JavaScript.h
+ JavaScriptCore.h
+ OpaqueJSString.h
+ WebKitAvailability.h
+) do (
+ xcopy /y /d ..\..\API\%%f "%PublicHeadersDirectory%" >NUL
+)
+
+echo Copying private headers...
+mkdir "%PrivateHeadersDirectory%" 2>NUL
+for %%d in (
+ assembler
+ bytecode
+ dfg
+ heap
+ debugger
+ interpreter
+ jit
+ llint
+ parser
+ profiler
+ runtime
+ yarr
+) do (
+ xcopy /y /d ..\..\%%d\*.h "%PrivateHeadersDirectory%" >NUL
+)
+
+echo Copying resources...
+mkdir "%ResourcesDirectory%" 2>NUL
+xcopy /y /d ..\JavaScriptCore.resources\* "%ResourcesDirectory%" >NUL
+
+goto :EOF
+
+:clean
+
+echo Deleting copied files...
+if exist "%PublicHeadersDirectory%" rmdir /s /q "%PublicHeadersDirectory%" >NUL
+if exist "%PrivateHeadersDirectory%" rmdir /s /q "%PrivateHeadersDirectory%" >NUL
+if exist "%ResourcesDirectory%" rmdir /s /q "%ResourcesDirectory%" >NUL
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCoreSubmit.sln b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCoreSubmit.sln
index 1e24f2870..2ff339fb1 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCoreSubmit.sln
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCoreSubmit.sln
@@ -3,26 +3,33 @@ Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JavaScriptCore", "JavaScriptCore\JavaScriptCore.vcproj", "{011D10F1-B656-4A1B-A0C3-3842F02122C5}"
ProjectSection(ProjectDependencies) = postProject
- {AA8A5A85-592B-4357-BC60-E0E91E026AF6} = {AA8A5A85-592B-4357-BC60-E0E91E026AF6}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WTF", "WTF\WTF.vcproj", "{AA8A5A85-592B-4357-BC60-E0E91E026AF6}"
- ProjectSection(ProjectDependencies) = postProject
{4FF5BA11-59EC-4C24-8F52-F235C2E7D43A} = {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JavaScriptCoreGenerated", "JavaScriptCore\JavaScriptCoreGenerated.vcproj", "{4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}"
+ ProjectSection(ProjectDependencies) = postProject
+ {AA8A5A85-592B-4357-BC60-E0E91E026AF6} = {AA8A5A85-592B-4357-BC60-E0E91E026AF6}
+ EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jsc", "jsc\jsc.vcproj", "{C59E5129-B453-49B7-A52B-1E104715F76E}"
ProjectSection(ProjectDependencies) = postProject
{011D10F1-B656-4A1B-A0C3-3842F02122C5} = {011D10F1-B656-4A1B-A0C3-3842F02122C5}
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WTF", "WTF\WTF.vcproj", "{AA8A5A85-592B-4357-BC60-E0E91E026AF6}"
+ ProjectSection(ProjectDependencies) = postProject
+ {5AE5F5E4-782D-4F63-B4D7-3977B52B9950} = {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WTFGenerated", "WTF\WTFGenerated.vcproj", "{5AE5F5E4-782D-4F63-B4D7-3977B52B9950}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug_All|Win32 = Debug_All|Win32
+ Debug_Cairo_CFLite|Win32 = Debug_Cairo_CFLite|Win32
Debug|Win32 = Debug|Win32
Production|Win32 = Production|Win32
+ Release_Cairo_CFLite|Win32 = Release_Cairo_CFLite|Win32
Release_PGO_Optimize|Win32 = Release_PGO_Optimize|Win32
Release_PGO|Win32 = Release_PGO|Win32
Release|Win32 = Release|Win32
@@ -30,34 +37,30 @@ Global
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{011D10F1-B656-4A1B-A0C3-3842F02122C5}.Debug_All|Win32.ActiveCfg = Debug_All|Win32
{011D10F1-B656-4A1B-A0C3-3842F02122C5}.Debug_All|Win32.Build.0 = Debug_All|Win32
+ {011D10F1-B656-4A1B-A0C3-3842F02122C5}.Debug_Cairo_CFLite|Win32.ActiveCfg = Debug_Cairo_CFLite|Win32
+ {011D10F1-B656-4A1B-A0C3-3842F02122C5}.Debug_Cairo_CFLite|Win32.Build.0 = Debug_Cairo_CFLite|Win32
{011D10F1-B656-4A1B-A0C3-3842F02122C5}.Debug|Win32.ActiveCfg = Debug|Win32
{011D10F1-B656-4A1B-A0C3-3842F02122C5}.Debug|Win32.Build.0 = Debug|Win32
{011D10F1-B656-4A1B-A0C3-3842F02122C5}.Production|Win32.ActiveCfg = Production|Win32
{011D10F1-B656-4A1B-A0C3-3842F02122C5}.Production|Win32.Build.0 = Production|Win32
+ {011D10F1-B656-4A1B-A0C3-3842F02122C5}.Release_Cairo_CFLite|Win32.ActiveCfg = Release_Cairo_CFLite|Win32
+ {011D10F1-B656-4A1B-A0C3-3842F02122C5}.Release_Cairo_CFLite|Win32.Build.0 = Release_Cairo_CFLite|Win32
{011D10F1-B656-4A1B-A0C3-3842F02122C5}.Release_PGO_Optimize|Win32.ActiveCfg = Release_PGO_Optimize|Win32
{011D10F1-B656-4A1B-A0C3-3842F02122C5}.Release_PGO_Optimize|Win32.Build.0 = Release_PGO_Optimize|Win32
{011D10F1-B656-4A1B-A0C3-3842F02122C5}.Release_PGO|Win32.ActiveCfg = Release_PGO|Win32
{011D10F1-B656-4A1B-A0C3-3842F02122C5}.Release_PGO|Win32.Build.0 = Release_PGO|Win32
{011D10F1-B656-4A1B-A0C3-3842F02122C5}.Release|Win32.ActiveCfg = Release|Win32
{011D10F1-B656-4A1B-A0C3-3842F02122C5}.Release|Win32.Build.0 = Release|Win32
- {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Debug_All|Win32.ActiveCfg = Debug_All|Win32
- {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Debug_All|Win32.Build.0 = Debug_All|Win32
- {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Debug|Win32.ActiveCfg = Debug|Win32
- {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Debug|Win32.Build.0 = Debug|Win32
- {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Production|Win32.ActiveCfg = Production|Win32
- {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Production|Win32.Build.0 = Production|Win32
- {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release_PGO_Optimize|Win32.ActiveCfg = Release_PGO|Win32
- {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release_PGO_Optimize|Win32.Build.0 = Release_PGO|Win32
- {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release_PGO|Win32.ActiveCfg = Release_PGO|Win32
- {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release_PGO|Win32.Build.0 = Release_PGO|Win32
- {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release|Win32.ActiveCfg = Release|Win32
- {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release|Win32.Build.0 = Release|Win32
{4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Debug_All|Win32.ActiveCfg = Debug_All|Win32
{4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Debug_All|Win32.Build.0 = Debug_All|Win32
+ {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Debug_Cairo_CFLite|Win32.ActiveCfg = Debug_Cairo_CFLite|Win32
+ {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Debug_Cairo_CFLite|Win32.Build.0 = Debug_Cairo_CFLite|Win32
{4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Debug|Win32.ActiveCfg = Debug|Win32
{4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Debug|Win32.Build.0 = Debug|Win32
{4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Production|Win32.ActiveCfg = Production|Win32
{4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Production|Win32.Build.0 = Production|Win32
+ {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release_Cairo_CFLite|Win32.ActiveCfg = Release_Cairo_CFLite|Win32
+ {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release_Cairo_CFLite|Win32.Build.0 = Release_Cairo_CFLite|Win32
{4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release_PGO_Optimize|Win32.ActiveCfg = Release_PGO|Win32
{4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release_PGO_Optimize|Win32.Build.0 = Release_PGO|Win32
{4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release_PGO|Win32.ActiveCfg = Release_PGO|Win32
@@ -66,16 +69,52 @@ Global
{4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release|Win32.Build.0 = Release|Win32
{C59E5129-B453-49B7-A52B-1E104715F76E}.Debug_All|Win32.ActiveCfg = Debug_All|Win32
{C59E5129-B453-49B7-A52B-1E104715F76E}.Debug_All|Win32.Build.0 = Debug_All|Win32
+ {C59E5129-B453-49B7-A52B-1E104715F76E}.Debug_Cairo_CFLite|Win32.ActiveCfg = Debug_Cairo_CFLite|Win32
+ {C59E5129-B453-49B7-A52B-1E104715F76E}.Debug_Cairo_CFLite|Win32.Build.0 = Debug_Cairo_CFLite|Win32
{C59E5129-B453-49B7-A52B-1E104715F76E}.Debug|Win32.ActiveCfg = Debug|Win32
{C59E5129-B453-49B7-A52B-1E104715F76E}.Debug|Win32.Build.0 = Debug|Win32
{C59E5129-B453-49B7-A52B-1E104715F76E}.Production|Win32.ActiveCfg = Production|Win32
{C59E5129-B453-49B7-A52B-1E104715F76E}.Production|Win32.Build.0 = Production|Win32
+ {C59E5129-B453-49B7-A52B-1E104715F76E}.Release_Cairo_CFLite|Win32.ActiveCfg = Release_Cairo_CFLite|Win32
+ {C59E5129-B453-49B7-A52B-1E104715F76E}.Release_Cairo_CFLite|Win32.Build.0 = Release_Cairo_CFLite|Win32
{C59E5129-B453-49B7-A52B-1E104715F76E}.Release_PGO_Optimize|Win32.ActiveCfg = Release_PGO|Win32
{C59E5129-B453-49B7-A52B-1E104715F76E}.Release_PGO_Optimize|Win32.Build.0 = Release_PGO|Win32
{C59E5129-B453-49B7-A52B-1E104715F76E}.Release_PGO|Win32.ActiveCfg = Release_PGO|Win32
{C59E5129-B453-49B7-A52B-1E104715F76E}.Release_PGO|Win32.Build.0 = Release_PGO|Win32
{C59E5129-B453-49B7-A52B-1E104715F76E}.Release|Win32.ActiveCfg = Release|Win32
{C59E5129-B453-49B7-A52B-1E104715F76E}.Release|Win32.Build.0 = Release|Win32
+ {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Debug_All|Win32.ActiveCfg = Debug_All|Win32
+ {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Debug_All|Win32.Build.0 = Debug_All|Win32
+ {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Debug_Cairo_CFLite|Win32.ActiveCfg = Debug_Cairo_CFLite|Win32
+ {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Debug_Cairo_CFLite|Win32.Build.0 = Debug_Cairo_CFLite|Win32
+ {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Debug|Win32.ActiveCfg = Debug|Win32
+ {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Debug|Win32.Build.0 = Debug|Win32
+ {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Production|Win32.ActiveCfg = Production|Win32
+ {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Production|Win32.Build.0 = Production|Win32
+ {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release_Cairo_CFLite|Win32.ActiveCfg = Release_Cairo_CFLite|Win32
+ {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release_Cairo_CFLite|Win32.Build.0 = Release_Cairo_CFLite|Win32
+ {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release_PGO_Optimize|Win32.ActiveCfg = Production|Win32
+ {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release_PGO_Optimize|Win32.Build.0 = Production|Win32
+ {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release_PGO|Win32.ActiveCfg = Production|Win32
+ {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release_PGO|Win32.Build.0 = Production|Win32
+ {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release|Win32.ActiveCfg = Release|Win32
+ {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release|Win32.Build.0 = Release|Win32
+ {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}.Debug_All|Win32.ActiveCfg = Debug_All|Win32
+ {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}.Debug_All|Win32.Build.0 = Debug_All|Win32
+ {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}.Debug_Cairo_CFLite|Win32.ActiveCfg = Debug_Cairo_CFLite|Win32
+ {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}.Debug_Cairo_CFLite|Win32.Build.0 = Debug_Cairo_CFLite|Win32
+ {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}.Debug|Win32.ActiveCfg = Debug|Win32
+ {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}.Debug|Win32.Build.0 = Debug|Win32
+ {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}.Production|Win32.ActiveCfg = Production|Win32
+ {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}.Production|Win32.Build.0 = Production|Win32
+ {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}.Release_Cairo_CFLite|Win32.ActiveCfg = Release_Cairo_CFLite|Win32
+ {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}.Release_Cairo_CFLite|Win32.Build.0 = Release_Cairo_CFLite|Win32
+ {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}.Release_PGO_Optimize|Win32.ActiveCfg = Production|Win32
+ {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}.Release_PGO_Optimize|Win32.Build.0 = Production|Win32
+ {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}.Release_PGO|Win32.ActiveCfg = Production|Win32
+ {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}.Release_PGO|Win32.Build.0 = Production|Win32
+ {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}.Release|Win32.ActiveCfg = Release|Win32
+ {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
index 5689b2608..3bf7817f3 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
@@ -328,58 +328,6 @@
Name="VCPostBuildEventTool"
/>
</Configuration>
- <Configuration
- Name="Release_PGO|Win32"
- ConfigurationType="4"
- InheritedPropertySheets=".\WTFReleasePGO.vsprops"
- CharacterSet="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
</Configurations>
<References>
</References>
@@ -512,93 +460,85 @@
>
</File>
</Filter>
- <Filter
- Name="dtoa"
- >
- <File
- RelativePath="..\..\wtf\dtoa\bignum-dtoa.cc"
- >
- </File>
- <File
- RelativePath="..\..\wtf\dtoa\bignum-dtoa.h"
- >
- </File>
- <File
- RelativePath="..\..\wtf\dtoa\bignum.cc"
- >
- </File>
- <File
- RelativePath="..\..\wtf\dtoa\bignum.h"
- >
- </File>
- <File
- RelativePath="..\..\wtf\dtoa\cached-powers.cc"
- >
- </File>
- <File
- RelativePath="..\..\wtf\dtoa\cached-powers.h"
- >
- </File>
- <File
- RelativePath="..\..\wtf\dtoa\diy-fp.cc"
- >
- </File>
- <File
- RelativePath="..\..\wtf\dtoa\diy-fp.h"
- >
- </File>
- <File
- RelativePath="..\..\wtf\dtoa\double-conversion.cc"
- >
- </File>
- <File
- RelativePath="..\..\wtf\dtoa\double-conversion.h"
- >
- </File>
- <File
- RelativePath="..\..\wtf\dtoa\double.h"
- >
- </File>
- <File
- RelativePath="..\..\wtf\dtoa\fast-dtoa.cc"
- >
- </File>
- <File
- RelativePath="..\..\wtf\dtoa\fast-dtoa.h"
- >
- </File>
- <File
- RelativePath="..\..\wtf\dtoa\fixed-dtoa.cc"
- >
- </File>
- <File
- RelativePath="..\..\wtf\dtoa\fixed-dtoa.h"
- >
- </File>
- <File
- RelativePath="..\..\wtf\dtoa\strtod.cc"
- >
- </File>
- <File
- RelativePath="..\..\wtf\dtoa\strtod.h"
- >
- </File>
- <File
- RelativePath="..\..\wtf\dtoa\utils.h"
- >
- </File>
- </Filter>
+ <Filter
+ Name="dtoa"
+ >
+ <File
+ RelativePath="..\..\wtf\dtoa\bignum-dtoa.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\dtoa\bignum-dtoa.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\dtoa\bignum.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\dtoa\bignum.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\dtoa\cached-powers.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\dtoa\cached-powers.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\dtoa\diy-fp.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\dtoa\diy-fp.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\dtoa\double-conversion.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\dtoa\double-conversion.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\dtoa\double.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\dtoa\fast-dtoa.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\dtoa\fast-dtoa.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\dtoa\fixed-dtoa.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\dtoa\fixed-dtoa.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\dtoa\strtod.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\dtoa\strtod.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\dtoa\utils.h"
+ >
+ </File>
+ </Filter>
<Filter
Name="threads"
>
- <Filter
- Name="win"
- >
- <File
- RelativePath="..\..\wtf\threads\win\BinarySemaphoreWin.cpp"
- >
- </File>
- </Filter>
<File
RelativePath="..\..\wtf\threads\BinarySemaphore.cpp"
>
@@ -607,6 +547,14 @@
RelativePath="..\..\wtf\threads\BinarySemaphore.h"
>
</File>
+ <Filter
+ Name="win"
+ >
+ <File
+ RelativePath="..\..\wtf\threads\win\BinarySemaphoreWin.cpp"
+ >
+ </File>
+ </Filter>
</Filter>
<File
RelativePath="..\..\wtf\Alignment.h"
@@ -653,15 +601,15 @@
>
</File>
<File
- RelativePath="..\..\wtf\BitVector.cpp"
+ RelativePath="..\..\wtf\Bitmap.h"
>
</File>
<File
- RelativePath="..\..\wtf\BitVector.h"
+ RelativePath="..\..\wtf\BitVector.cpp"
>
</File>
<File
- RelativePath="..\..\wtf\Bitmap.h"
+ RelativePath="..\..\wtf\BitVector.h"
>
</File>
<File
@@ -721,23 +669,23 @@
>
</File>
<File
- RelativePath="..\..\wtf\DecimalNumber.cpp"
+ RelativePath="..\..\wtf\DataLog.cpp"
>
</File>
<File
- RelativePath="..\..\wtf\DecimalNumber.h"
+ RelativePath="..\..\wtf\DataLog.h"
>
</File>
<File
- RelativePath="..\..\wtf\Decoder.h"
+ RelativePath="..\..\wtf\DecimalNumber.cpp"
>
</File>
<File
- RelativePath="..\..\wtf\DataLog.cpp"
+ RelativePath="..\..\wtf\DecimalNumber.h"
>
</File>
<File
- RelativePath="..\..\wtf\DataLog.h"
+ RelativePath="..\..\wtf\Decoder.h"
>
</File>
<File
@@ -753,27 +701,19 @@
>
</File>
<File
- RelativePath="..\..\wtf\DynamicAnnotations.cpp"
- >
- </File>
- <File
- RelativePath="..\..\wtf\DynamicAnnotations.h"
- >
- </File>
- <File
- RelativePath="..\..\wtf\Float32Array.h"
+ RelativePath="..\..\wtf\dtoa.cpp"
>
</File>
<File
- RelativePath="..\..\wtf\Float64Array.h"
+ RelativePath="..\..\wtf\dtoa.h"
>
</File>
<File
- RelativePath="..\..\wtf\dtoa.cpp"
+ RelativePath="..\..\wtf\DynamicAnnotations.cpp"
>
</File>
<File
- RelativePath="..\..\wtf\dtoa.h"
+ RelativePath="..\..\wtf\DynamicAnnotations.h"
>
</File>
<File
@@ -811,14 +751,6 @@
DisableSpecificWarnings="4702"
/>
</FileConfiguration>
- <FileConfiguration
- Name="Release_PGO|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- DisableSpecificWarnings="4702"
- />
- </FileConfiguration>
</File>
<File
RelativePath="..\..\wtf\FastMalloc.h"
@@ -829,6 +761,14 @@
>
</File>
<File
+ RelativePath="..\..\wtf\Float32Array.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\Float64Array.h"
+ >
+ </File>
+ <File
RelativePath="..\..\wtf\Forward.h"
>
</File>
@@ -917,27 +857,27 @@
>
</File>
<File
- RelativePath="..\..\wtf\MetaAllocator.cpp"
+ RelativePath="..\..\wtf\MD5.cpp"
>
</File>
<File
- RelativePath="..\..\wtf\MetaAllocator.h"
+ RelativePath="..\..\wtf\MD5.h"
>
</File>
<File
- RelativePath="..\..\wtf\MetaAllocatorHandle.h"
+ RelativePath="..\..\wtf\MessageQueue.h"
>
</File>
<File
- RelativePath="..\..\wtf\MD5.cpp"
+ RelativePath="..\..\wtf\MetaAllocator.cpp"
>
</File>
<File
- RelativePath="..\..\wtf\MD5.h"
+ RelativePath="..\..\wtf\MetaAllocator.h"
>
</File>
<File
- RelativePath="..\..\wtf\MessageQueue.h"
+ RelativePath="..\..\wtf\MetaAllocatorHandle.h"
>
</File>
<File
@@ -1021,39 +961,39 @@
>
</File>
<File
- RelativePath="..\..\wtf\PassOwnArrayPtr.h"
+ RelativePath="..\..\wtf\ParallelJobs.h"
>
</File>
<File
- RelativePath="..\..\wtf\PassOwnPtr.h"
+ RelativePath="..\..\wtf\ParallelJobsGeneric.cpp"
>
</File>
<File
- RelativePath="..\..\wtf\PassRefPtr.h"
+ RelativePath="..\..\wtf\ParallelJobsGeneric.h"
>
</File>
<File
- RelativePath="..\..\wtf\PassTraits.h"
+ RelativePath="..\..\wtf\ParallelJobsLibdispatch.h"
>
</File>
<File
- RelativePath="..\..\wtf\ParallelJobs.h"
+ RelativePath="..\..\wtf\ParallelJobsOpenMP.h"
>
</File>
<File
- RelativePath="..\..\wtf\ParallelJobsGeneric.cpp"
+ RelativePath="..\..\wtf\PassOwnArrayPtr.h"
>
</File>
<File
- RelativePath="..\..\wtf\ParallelJobsGeneric.h"
+ RelativePath="..\..\wtf\PassOwnPtr.h"
>
</File>
<File
- RelativePath="..\..\wtf\ParallelJobsLibdispatch.h"
+ RelativePath="..\..\wtf\PassRefPtr.h"
>
</File>
<File
- RelativePath="..\..\wtf\ParallelJobsOpenMP.h"
+ RelativePath="..\..\wtf\PassTraits.h"
>
</File>
<File
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGenerated.make b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGenerated.make
new file mode 100644
index 000000000..e7896fdfb
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGenerated.make
@@ -0,0 +1,13 @@
+all:
+ touch "%ConfigurationBuildDir%\buildfailed"
+ bash build-generated-files.sh "%ConfigurationBuildDir%" "$(WEBKITLIBRARIESDIR)"
+!IF "$(OFFICIAL_BUILD)"!="1"
+ bash -c "python work-around-vs-dependency-tracking-bugs.py"
+!ENDIF
+ copy-files.cmd
+
+ -del "%ConfigurationBuildDir%\buildfailed"
+
+clean:
+ -del "%ConfigurationBuildDir%\buildfailed"
+ copy-files.cmd clean
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGenerated.vcproj b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGenerated.vcproj
new file mode 100644
index 000000000..3cb825062
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGenerated.vcproj
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="WTFGenerated"
+ ProjectGUID="{5AE5F5E4-782D-4F63-B4D7-3977B52B9950}"
+ RootNamespace="WTFGenerated"
+ Keyword="MakeFileProj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ ConfigurationType="0"
+ InheritedPropertySheets=".\WTFGeneratedDebug.vsprops"
+ >
+ <Tool
+ Name="VCNMakeTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug_All|Win32"
+ ConfigurationType="0"
+ InheritedPropertySheets=".\WTFGeneratedDebugAll.vsprops"
+ >
+ <Tool
+ Name="VCNMakeTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ ConfigurationType="0"
+ InheritedPropertySheets=".\WTFGeneratedRelease.vsprops"
+ >
+ <Tool
+ Name="VCNMakeTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Production|Win32"
+ ConfigurationType="0"
+ InheritedPropertySheets=".\WTFGeneratedProduction.vsprops"
+ >
+ <Tool
+ Name="VCNMakeTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release_Cairo_CFLite|Win32"
+ ConfigurationType="0"
+ InheritedPropertySheets=".\WTFGeneratedReleaseCairoCFLite.vsprops"
+ >
+ <Tool
+ Name="VCNMakeTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug_Cairo_CFLite|Win32"
+ ConfigurationType="0"
+ InheritedPropertySheets=".\WTFGeneratedDebugCairoCFLite.vsprops"
+ >
+ <Tool
+ Name="VCNMakeTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <File
+ RelativePath=".\build-generated-files.sh"
+ >
+ </File>
+ <File
+ RelativePath=".\copy-files.cmd"
+ >
+ </File>
+ <File
+ RelativePath=".\work-around-vs-dependency-tracking-bugs.py"
+ >
+ </File>
+ <File
+ RelativePath=".\WTFGenerated.make"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGeneratedCommon.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGeneratedCommon.vsprops
new file mode 100644
index 000000000..5173df8ef
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGeneratedCommon.vsprops
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="WTFGeneratedCommon"
+ OutputDirectory="$(ConfigurationBuildDir)\lib"
+ >
+ <Tool
+ Name="VCNMakeTool"
+ BuildCommandLine="%SystemDrive%\cygwin\bin\which.exe bash&#x0D;&#x0A;if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%&#x0D;&#x0A;cmd /c&#x0D;&#x0A;&#x0D;&#x0A;set CONFIGURATIONBUILDDIR=$(WebKitOutputDir)\$(ConfigurationName)&#x0D;&#x0A;set PRODUCTION=$(PRODUCTION)&#x0D;&#x0A;nmake /nologo -f WTFGenerated.make"
+ ReBuildCommandLine="%SystemDrive%\cygwin\bin\which.exe bash&#x0D;&#x0A;if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%&#x0D;&#x0A;cmd /c&#x0D;&#x0A;&#x0D;&#x0A;set CONFIGURATIONBUILDDIR=$(WebKitOutputDir)\$(ConfigurationName)&#x0D;&#x0A;set PRODUCTION=$(PRODUCTION)&#x0D;&#x0A;nmake /nologo -f WTFGenerated.make clean&#x0D;&#x0A;nmake -f WTFGenerated.make"
+ CleanCommandLine="%SystemDrive%\cygwin\bin\which.exe bash&#x0D;&#x0A;if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%&#x0D;&#x0A;cmd /c&#x0D;&#x0A;&#x0D;&#x0A;set CONFIGURATIONBUILDDIR=$(WebKitOutputDir)\$(ConfigurationName)&#x0D;&#x0A;set PRODUCTION=$(PRODUCTION)&#x0D;&#x0A;nmake /nologo -f WTFGenerated.make clean"
+ />
+</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGeneratedDebug.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGeneratedDebug.vsprops
new file mode 100644
index 000000000..bc16aca94
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGeneratedDebug.vsprops
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="WTFGeneratedDebug"
+ InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefines.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;.\WTFGeneratedCommon.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGeneratedDebugAll.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGeneratedDebugAll.vsprops
new file mode 100644
index 000000000..cacea402c
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGeneratedDebugAll.vsprops
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="WTFGeneratedDebugAll"
+ InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefines.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug_all.vsprops;.\WTFGeneratedCommon.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGeneratedDebugCairoCFLite.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGeneratedDebugCairoCFLite.vsprops
new file mode 100644
index 000000000..fbc371372
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGeneratedDebugCairoCFLite.vsprops
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="WTFGeneratedDebugCairoCFLite"
+ InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefinesCairo.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug_wincairo.vsprops;.\WTFGeneratedCommon.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGeneratedProduction.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGeneratedProduction.vsprops
new file mode 100644
index 000000000..3e49ed6ea
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGeneratedProduction.vsprops
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="WTFGeneratedProduction"
+ InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefines.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\releaseproduction.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\production.vsprops;.\WTFGeneratedCommon.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFReleasePGO.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGeneratedRelease.vsprops
index 41b7f7bfa..74a4debaa 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFReleasePGO.vsprops
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGeneratedRelease.vsprops
@@ -2,7 +2,7 @@
<VisualStudioPropertySheet
ProjectType="Visual C++"
Version="8.00"
- Name="WTFReleasePGO"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefines.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\releaseproduction.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\production.vsprops;.\WTFCommon.vsprops"
+ Name="WTFGeneratedRelease"
+ InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefines.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\releaseproduction.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;.\WTFGeneratedCommon.vsprops"
>
</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGeneratedReleaseCairoCFLite.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGeneratedReleaseCairoCFLite.vsprops
new file mode 100644
index 000000000..730d71941
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFGeneratedReleaseCairoCFLite.vsprops
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="WTFGeneratedReleaseCairoCFLite"
+ InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefinesCairo.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\releaseproduction.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\WinCairo.vsprops;.\WTFGeneratedCommon.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/build-generated-files.sh b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/build-generated-files.sh
new file mode 100755
index 000000000..d1a4e560f
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/build-generated-files.sh
@@ -0,0 +1,11 @@
+#!/usr/bin/bash
+
+# Determine whether we have the versioned ICU 4.0 or the unversioned ICU 4.4
+UNVERSIONED_ICU_LIB_PATH=$(cygpath -u "${WEBKITLIBRARIESDIR}/lib/libicuuc.lib")
+ICUVERSION_H_PATH=$(cygpath -u "${CONFIGURATIONBUILDDIR}/include/private/ICUVersion.h")
+if test \( ! -f "${ICUVERSION_H_PATH}" \) -o \( -f "${UNVERSIONED_ICU_LIB_PATH}" -a \( "${UNVERSIONED_ICU_LIB_PATH}" -nt "${ICUVERSION_H_PATH}" \) \)
+then
+ mkdir -p "$(dirname "${ICUVERSION_H_PATH}")"
+ test ! -f "${UNVERSIONED_ICU_LIB_PATH}"
+ echo "#define U_DISABLE_RENAMING $?" > "${ICUVERSION_H_PATH}"
+fi
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/copy-files.cmd b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/copy-files.cmd
new file mode 100755
index 000000000..3160e5cc1
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/copy-files.cmd
@@ -0,0 +1,37 @@
+@echo off
+
+set PrivateHeadersDirectory=%CONFIGURATIONBUILDDIR%\include\private\JavaScriptCore
+
+if "%1" EQU "clean" goto :clean
+if "%1" EQU "rebuild" call :clean
+
+echo Copying WTF headers...
+for %%d in (
+ wtf
+ wtf\dtoa
+ wtf\text
+ wtf\threads
+ wtf\unicode
+ wtf\unicode\icu
+) do (
+ mkdir "%PrivateHeadersDirectory%\%%d" 2>NUL
+ xcopy /y /d ..\..\%%d\*.h "%PrivateHeadersDirectory%\%%d" >NUL
+)
+
+echo Copying other files...
+for %%f in (
+ create_hash_table
+ wtf\text\AtomicString.cpp
+ wtf\text\StringBuilder.cpp
+ wtf\text\StringImpl.cpp
+ wtf\text\WTFString.cpp
+) do (
+ echo F | xcopy /y /d ..\..\%%f "%PrivateHeadersDirectory%\%%f" >NUL
+)
+
+goto :EOF
+
+:clean
+
+echo Deleting copied files...
+if exist "%PrivateHeadersDirectory%" rmdir /s /q "%PrivateHeadersDirectory%" >NUL
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/work-around-vs-dependency-tracking-bugs.py b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/work-around-vs-dependency-tracking-bugs.py
index 5060f69c4..5060f69c4 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/work-around-vs-dependency-tracking-bugs.py
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/work-around-vs-dependency-tracking-bugs.py
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jsc.vcproj b/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jsc.vcproj
index a650cd2e5..21f13fc47 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jsc.vcproj
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jsc.vcproj
@@ -448,7 +448,7 @@
</References>
<Files>
<File
- RelativePath="$(ConfigurationBuildDir)\include\private\JavaScriptCore\AtomicString.cpp"
+ RelativePath="$(ConfigurationBuildDir)\include\private\JavaScriptCore\wtf\text\AtomicString.cpp"
>
</File>
<File
@@ -456,15 +456,15 @@
>
</File>
<File
- RelativePath="$(ConfigurationBuildDir)\include\private\JavaScriptCore\StringBuilder.cpp"
+ RelativePath="$(ConfigurationBuildDir)\include\private\JavaScriptCore\wtf\text\StringBuilder.cpp"
>
</File>
<File
- RelativePath="$(ConfigurationBuildDir)\include\private\JavaScriptCore\StringImpl.cpp"
+ RelativePath="$(ConfigurationBuildDir)\include\private\JavaScriptCore\wtf\text\StringImpl.cpp"
>
</File>
<File
- RelativePath="$(ConfigurationBuildDir)\include\private\JavaScriptCore\WTFString.cpp"
+ RelativePath="$(ConfigurationBuildDir)\include\private\JavaScriptCore\wtf\text\WTFString.cpp"
>
</File>
</Files>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExp.vcproj b/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExp.vcproj
index b80b059f6..6d44dce91 100755
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExp.vcproj
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExp.vcproj
@@ -448,15 +448,15 @@
</References>
<Files>
<File
- RelativePath="$(ConfigurationBuildDir)\include\private\JavaScriptCore\AtomicString.cpp"
+ RelativePath="$(ConfigurationBuildDir)\include\private\JavaScriptCore\wtf\text\AtomicString.cpp"
>
</File>
<File
- RelativePath="$(ConfigurationBuildDir)\include\private\JavaScriptCore\StringBuilder.cpp"
+ RelativePath="$(ConfigurationBuildDir)\include\private\JavaScriptCore\wtf\text\StringBuilder.cpp"
>
</File>
<File
- RelativePath="$(ConfigurationBuildDir)\include\private\JavaScriptCore\StringImpl.cpp"
+ RelativePath="$(ConfigurationBuildDir)\include\private\JavaScriptCore\wtf\text\StringImpl.cpp"
>
</File>
<File
@@ -464,7 +464,7 @@
>
</File>
<File
- RelativePath="$(ConfigurationBuildDir)\include\private\JavaScriptCore\WTFString.cpp"
+ RelativePath="$(ConfigurationBuildDir)\include\private\JavaScriptCore\wtf\text\WTFString.cpp"
>
</File>
</Files>
diff --git a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
index d9d8e1631..a72046e2c 100644
--- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
+++ b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
@@ -49,17 +49,13 @@
/* Begin PBXBuildFile section */
06D358B30DAADAA4003B174E /* MainThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 06D358A20DAAD9C4003B174E /* MainThread.cpp */; };
06D358B40DAADAAA003B174E /* MainThreadMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 06D358A10DAAD9C4003B174E /* MainThreadMac.mm */; };
- 081469491264378500DFF935 /* StringBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 081469481264375E00DFF935 /* StringBuilder.h */; settings = {ATTRIBUTES = (Private, ); }; };
088FA5BB0EF76D4300578E6F /* RandomNumber.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 088FA5B90EF76D4300578E6F /* RandomNumber.cpp */; };
- 088FA5BC0EF76D4300578E6F /* RandomNumber.h in Headers */ = {isa = PBXBuildFile; fileRef = 088FA5BA0EF76D4300578E6F /* RandomNumber.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 08CABBA61265AB3900B206CE /* StringConcatenate.h in Headers */ = {isa = PBXBuildFile; fileRef = 0896C29E1265AB0900B1CDD3 /* StringConcatenate.h */; settings = {ATTRIBUTES = (Private, ); }; };
08DDA5C11264631700751732 /* UStringBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 08DDA5BB12645F1D00751732 /* UStringBuilder.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 08E279E90EF83B10007DB523 /* RandomNumberSeed.h in Headers */ = {isa = PBXBuildFile; fileRef = 08E279E80EF83B10007DB523 /* RandomNumberSeed.h */; };
+ 0A4337BB1506218800991C95 /* DFGRedundantPhiEliminationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0A4337BA1506218800991C95 /* DFGRedundantPhiEliminationPhase.cpp */; };
+ 0A4337BE1506219B00991C95 /* DFGRedundantPhiEliminationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0A4337BD1506219B00991C95 /* DFGRedundantPhiEliminationPhase.h */; };
0B330C270F38C62300692DE3 /* TypeTraits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0B330C260F38C62300692DE3 /* TypeTraits.cpp */; };
- 0B4D7E630F319AC800AD7E58 /* TypeTraits.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B4D7E620F319AC800AD7E58 /* TypeTraits.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 0BAC94A01338728400CF135B /* ThreadRestrictionVerifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BAC949E1338728400CF135B /* ThreadRestrictionVerifier.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 0BCD83571485845200EA2003 /* TemporaryChange.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BCD83541485841200EA2003 /* TemporaryChange.h */; settings = {ATTRIBUTES = (Private, ); }; };
0BF28A2911A33DC300638F84 /* SizeLimits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0BF28A2811A33DC300638F84 /* SizeLimits.cpp */; };
+ 0F0776BF14FF002B00102332 /* JITCompilationEffort.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0776BD14FF002800102332 /* JITCompilationEffort.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F0B839A14BCF45D00885B4F /* LLIntEntrypoints.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F0B839514BCF45A00885B4F /* LLIntEntrypoints.cpp */; };
0F0B839B14BCF46000885B4F /* LLIntEntrypoints.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0B839614BCF45A00885B4F /* LLIntEntrypoints.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F0B839C14BCF46300885B4F /* LLIntThunks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F0B839714BCF45A00885B4F /* LLIntThunks.cpp */; };
@@ -77,6 +73,7 @@
0F0FC45A14BD15F500B81154 /* LLIntCallLinkInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0FC45814BD15F100B81154 /* LLIntCallLinkInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F15F15F14B7A73E005DE37D /* CommonSlowPaths.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F16D726142C39C000CF784A /* BitVector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F16D724142C39A200CF784A /* BitVector.cpp */; };
+ 0F1D0861150C5A860074D109 /* DFGNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F1D085F150C5A800074D109 /* DFGNode.cpp */; };
0F21C26814BE5F6800ADC64B /* JITDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C26614BE5F5E00ADC64B /* JITDriver.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F21C27C14BE727600ADC64B /* ExecutionHarness.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C27A14BE727300ADC64B /* ExecutionHarness.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F21C27D14BE727A00ADC64B /* CodeSpecializationKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C27914BE727300ADC64B /* CodeSpecializationKind.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -84,7 +81,6 @@
0F242DA713F3B1E8007ADD4C /* WeakReferenceHarvester.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F242DA513F3B1BB007ADD4C /* WeakReferenceHarvester.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F2C556F14738F3100121E4F /* DFGCodeBlocks.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2C556E14738F2E00121E4F /* DFGCodeBlocks.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F2C557014738F3500121E4F /* DFGCodeBlocks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2C556D14738F2E00121E4F /* DFGCodeBlocks.cpp */; };
- 0F2E5BF7146357D5003EB2EB /* Spectrum.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2E5BF5146357D2003EB2EB /* Spectrum.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, ); }; };
@@ -105,6 +101,8 @@
0F4680D514BBD24B00BFE272 /* HostCallReturnValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4680D114BBC5F800BFE272 /* HostCallReturnValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F55F0F414D1063900AC7649 /* AbstractPC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F55F0F114D1063600AC7649 /* AbstractPC.cpp */; };
0F55F0F514D1063C00AC7649 /* AbstractPC.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F55F0F214D1063600AC7649 /* AbstractPC.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0F56A1D315000F35002992B1 /* ExecutionCounter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F56A1D115000F31002992B1 /* ExecutionCounter.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0F56A1D515001CF4002992B1 /* ExecutionCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F56A1D415001CF2002992B1 /* ExecutionCounter.cpp */; };
0F5F08CF146C7633000472A9 /* UnconditionalFinalizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5F08CE146C762F000472A9 /* UnconditionalFinalizer.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F620174143FCD330068B77C /* DFGVariableAccessData.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F620172143FCD2F0068B77C /* DFGVariableAccessData.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F620175143FCD370068B77C /* DFGOperands.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F620171143FCD2F0068B77C /* DFGOperands.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -112,7 +110,6 @@
0F620177143FCD3F0068B77C /* DFGAbstractValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F62016F143FCD2F0068B77C /* DFGAbstractValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F620178143FCD440068B77C /* DFGAbstractState.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F62016E143FCD2F0068B77C /* DFGAbstractState.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F620179143FCD480068B77C /* DFGAbstractState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F62016D143FCD2F0068B77C /* DFGAbstractState.cpp */; };
- 0F636DA0142D27D700B2E66A /* PackedIntVector.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F636D9F142D27D200B2E66A /* PackedIntVector.h */; };
0F66E16B14DF3F1600B7B2E4 /* DFGNodeReferenceBlob.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F66E16814DF3F1300B7B2E4 /* DFGNodeReferenceBlob.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F66E16C14DF3F1600B7B2E4 /* DFGNodeUse.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F66E16914DF3F1300B7B2E4 /* DFGNodeUse.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F7700921402FF3C0078EB39 /* SamplingCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F7700911402FF280078EB39 /* SamplingCounter.cpp */; };
@@ -129,16 +126,12 @@
0F9332A314CA7DD70085F3C6 /* PutByIdStatus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F93329914CA7DC10085F3C6 /* PutByIdStatus.cpp */; };
0F9332A414CA7DD90085F3C6 /* PutByIdStatus.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F93329A14CA7DC10085F3C6 /* PutByIdStatus.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F9332A514CA7DDD0085F3C6 /* StructureSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F93329B14CA7DC10085F3C6 /* StructureSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 0F963B2713F753BB0002D9B2 /* RedBlackTree.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F963B2613F753990002D9B2 /* RedBlackTree.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F963B2C13F853EC0002D9B2 /* MetaAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F963B2B13F853C70002D9B2 /* MetaAllocator.cpp */; settings = {COMPILER_FLAGS = "-fno-strict-aliasing"; }; };
- 0F963B2D13F854020002D9B2 /* MetaAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F963B2A13F853BD0002D9B2 /* MetaAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 0F963B2F13FC66BB0002D9B2 /* MetaAllocatorHandle.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F963B2E13FC66AE0002D9B2 /* MetaAllocatorHandle.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F963B3813FC6FE90002D9B2 /* ValueProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F963B3613FC6FDE0002D9B2 /* ValueProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F9FC8C314E1B5FE00D52AE0 /* PolymorphicPutByIdList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F9FC8BF14E1B5FB00D52AE0 /* PolymorphicPutByIdList.cpp */; };
0F9FC8C414E1B60000D52AE0 /* PolymorphicPutByIdList.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F9FC8C014E1B5FB00D52AE0 /* PolymorphicPutByIdList.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F9FC8C514E1B60400D52AE0 /* PutKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F9FC8C114E1B5FB00D52AE0 /* PutKind.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F9FC8D014E612D800D52AE0 /* DataLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F9FC8CD14E612D500D52AE0 /* DataLog.cpp */; };
- 0F9FC8D114E612DA00D52AE0 /* DataLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F9FC8CE14E612D500D52AE0 /* DataLog.h */; settings = {ATTRIBUTES = (Private, ); }; };
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, ); }; };
@@ -164,16 +157,13 @@
0FC81516140511B500CFA603 /* VTableSpectrum.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC815121405118600CFA603 /* VTableSpectrum.cpp */; };
0FD3C82614115D4000FD81CB /* DFGDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FD3C82014115CF800FD81CB /* DFGDriver.cpp */; };
0FD3C82814115D4F00FD81CB /* DFGDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD3C82214115D0E00FD81CB /* DFGDriver.h */; };
- 0FD52AAE143035A00026DC9F /* UnionFind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD52AAC1430359D0026DC9F /* UnionFind.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FD82E2114172CE300179C94 /* DFGCapabilities.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FD82E1E14172C2F00179C94 /* DFGCapabilities.cpp */; };
0FD82E39141AB14D00179C94 /* CompactJITCodeMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD82E37141AB14200179C94 /* CompactJITCodeMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FD82E54141DAEEE00179C94 /* PredictedType.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD82E4F141DAEA100179C94 /* PredictedType.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FD82E55141DAEEE00179C94 /* PredictionTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD82E50141DAEA100179C94 /* PredictionTracker.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FD82E56141DAF0800179C94 /* DFGOSREntry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FD82E52141DAEDE00179C94 /* DFGOSREntry.cpp */; };
0FD82E57141DAF1000179C94 /* DFGOSREntry.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD82E53141DAEDE00179C94 /* DFGOSREntry.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 0FD82E85141F3FE300179C94 /* BoundsCheckedPointer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD82E82141F3FC900179C94 /* BoundsCheckedPointer.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FD82E86141F3FF100179C94 /* PredictedType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FD82E84141F3FDA00179C94 /* PredictedType.cpp */; };
- 0FD82F4B142806A100179C94 /* BitVector.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD82F491428069200179C94 /* BitVector.h */; settings = {ATTRIBUTES = (Private, ); }; };
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 */; };
0FF922D414F46B410041A24E /* LLIntOffsetsExtractor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4680A114BA7F8200BFE272 /* LLIntOffsetsExtractor.cpp */; };
@@ -189,7 +179,6 @@
0FFFC95E14EF90B700C72532 /* DFGPredictionPropagationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FFFC95214EF909500C72532 /* DFGPredictionPropagationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FFFC95F14EF90BB00C72532 /* DFGVirtualRegisterAllocationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FFFC95314EF909500C72532 /* DFGVirtualRegisterAllocationPhase.cpp */; };
0FFFC96014EF90BD00C72532 /* DFGVirtualRegisterAllocationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FFFC95414EF909500C72532 /* DFGVirtualRegisterAllocationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 1400067712A6F7830064D123 /* OSAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 1400067612A6F7830064D123 /* OSAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
1400069312A6F9E10064D123 /* OSAllocatorPosix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1400069212A6F9E10064D123 /* OSAllocatorPosix.cpp */; };
140566C4107EC255005DBC8D /* JSAPIValueWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC0894D50FAFBA2D00001865 /* JSAPIValueWrapper.cpp */; };
140566D1107EC267005DBC8D /* JSStaticScopeObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7E42C190E3938830065A544 /* JSStaticScopeObject.cpp */; };
@@ -253,7 +242,6 @@
1440F8920A508B100005F061 /* JSCallbackFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1440F8900A508B100005F061 /* JSCallbackFunction.cpp */; };
1440F8AF0A508D200005F061 /* JSCallbackConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1440F8AD0A508D200005F061 /* JSCallbackConstructor.cpp */; };
1440FCE40A51E46B0005F061 /* JSClassRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1440FCE20A51E46B0005F061 /* JSClassRef.cpp */; };
- 14456A321314657800212CA3 /* DoublyLinkedList.h in Headers */ = {isa = PBXBuildFile; fileRef = 14456A311314657800212CA3 /* DoublyLinkedList.h */; settings = {ATTRIBUTES = (Private, ); }; };
14469DD7107EC79E00650446 /* dtoa.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 651F6412039D5B5F0078395C /* dtoa.cpp */; };
14469DDE107EC7E700650446 /* Lookup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A8680255597D01FF60F7 /* Lookup.cpp */; };
14469DDF107EC7E700650446 /* MathObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A86A0255597D01FF60F7 /* MathObject.cpp */; };
@@ -318,7 +306,6 @@
14A42E3F0F4F60EE00599099 /* TimeoutChecker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14A42E3D0F4F60EE00599099 /* TimeoutChecker.cpp */; };
14A42E400F4F60EE00599099 /* TimeoutChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = 14A42E3E0F4F60EE00599099 /* TimeoutChecker.h */; settings = {ATTRIBUTES = (Private, ); }; };
14ABDF600A437FEF00ECCA01 /* JSCallbackObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14ABDF5E0A437FEF00ECCA01 /* JSCallbackObject.cpp */; };
- 14B3EF0512BC24DD00D29EFF /* PageBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 14B3EF0312BC24DD00D29EFF /* PageBlock.h */; settings = {ATTRIBUTES = (Private, ); }; };
14B3EF0612BC24DD00D29EFF /* PageBlock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14B3EF0412BC24DD00D29EFF /* PageBlock.cpp */; };
14B723B212D7DA46003BD5ED /* MachineStackMarker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14B7233F12D7D0DA003BD5ED /* MachineStackMarker.cpp */; };
14B723B812D7DA6F003BD5ED /* MachineStackMarker.h in Headers */ = {isa = PBXBuildFile; fileRef = 14B7234012D7D0DA003BD5ED /* MachineStackMarker.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -338,43 +325,20 @@
14F8BA43107EC88C009892DC /* TCSystemAlloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6541BD7008E80A17002CBEE7 /* TCSystemAlloc.cpp */; };
14F97447138C853E00DA1C67 /* HeapRootVisitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 14F97446138C853E00DA1C67 /* HeapRootVisitor.h */; settings = {ATTRIBUTES = (Private, ); }; };
14FFF98C12BFFF7500795BB8 /* PageAllocationAligned.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14FFF98A12BFFF7500795BB8 /* PageAllocationAligned.cpp */; };
- 14FFF98D12BFFF7500795BB8 /* PageAllocationAligned.h in Headers */ = {isa = PBXBuildFile; fileRef = 14FFF98B12BFFF7500795BB8 /* PageAllocationAligned.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 180B9B080F16D94F009BDBC5 /* CurrentTime.h in Headers */ = {isa = PBXBuildFile; fileRef = 180B9AF00F16C569009BDBC5 /* CurrentTime.h */; settings = {ATTRIBUTES = (Private, ); }; };
180B9BFE0F16E94D009BDBC5 /* CurrentTime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 180B9AEF0F16C569009BDBC5 /* CurrentTime.cpp */; };
18BAB55310DAE054000D945B /* ThreadIdentifierDataPthreads.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18BAB52710DADFCD000D945B /* ThreadIdentifierDataPthreads.cpp */; };
- 18BAB55410DAE066000D945B /* ThreadIdentifierDataPthreads.h in Headers */ = {isa = PBXBuildFile; fileRef = 18BAB52810DADFCD000D945B /* ThreadIdentifierDataPthreads.h */; };
1A082779142168D70090CCAC /* BinarySemaphore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A082777142168D70090CCAC /* BinarySemaphore.cpp */; };
1A08277A142168D70090CCAC /* BinarySemaphore.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A082778142168D70090CCAC /* BinarySemaphore.h */; };
- 1AA9E5511498093500001A8A /* Functional.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AA9E5501498093500001A8A /* Functional.h */; settings = {ATTRIBUTES = (Private, ); }; };
2684B2D314D4A9B20072C0B6 /* ParsedURL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2684B2C414D4A9B20072C0B6 /* ParsedURL.cpp */; };
- 2684B2D414D4A9B20072C0B6 /* ParsedURL.h in Headers */ = {isa = PBXBuildFile; fileRef = 2684B2C514D4A9B20072C0B6 /* ParsedURL.h */; };
- 2684B2D514D4A9B20072C0B6 /* URLString.h in Headers */ = {isa = PBXBuildFile; fileRef = 2684B2C614D4A9B20072C0B6 /* URLString.h */; };
- 2684B2D614D4A9B20072C0B6 /* RawURLBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 2684B2C814D4A9B20072C0B6 /* RawURLBuffer.h */; };
- 2684B2D714D4A9B20072C0B6 /* URLBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 2684B2C914D4A9B20072C0B6 /* URLBuffer.h */; };
2684B2D814D4A9B20072C0B6 /* URLCharacterTypes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2684B2CA14D4A9B20072C0B6 /* URLCharacterTypes.cpp */; };
- 2684B2D914D4A9B20072C0B6 /* URLCharacterTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 2684B2CB14D4A9B20072C0B6 /* URLCharacterTypes.h */; };
- 2684B2DA14D4A9B20072C0B6 /* URLComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 2684B2CC14D4A9B20072C0B6 /* URLComponent.h */; };
2684B2DB14D4A9B20072C0B6 /* URLEscape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2684B2CD14D4A9B20072C0B6 /* URLEscape.cpp */; };
- 2684B2DC14D4A9B20072C0B6 /* URLEscape.h in Headers */ = {isa = PBXBuildFile; fileRef = 2684B2CE14D4A9B20072C0B6 /* URLEscape.h */; };
- 2684B2DD14D4A9B20072C0B6 /* URLParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 2684B2CF14D4A9B20072C0B6 /* URLParser.h */; };
- 2684B2DE14D4A9B20072C0B6 /* URLQueryCanonicalizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 2684B2D014D4A9B20072C0B6 /* URLQueryCanonicalizer.h */; };
2684B2DF14D4A9B20072C0B6 /* URLSegments.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2684B2D114D4A9B20072C0B6 /* URLSegments.cpp */; };
- 2684B2E014D4A9B20072C0B6 /* URLSegments.h in Headers */ = {isa = PBXBuildFile; fileRef = 2684B2D214D4A9B20072C0B6 /* URLSegments.h */; };
- 2CFC5D1E12F45B48004914E2 /* CharacterNames.h in Headers */ = {isa = PBXBuildFile; fileRef = 2CFC5B7A12F44714004914E2 /* CharacterNames.h */; settings = {ATTRIBUTES = (Private, ); }; };
41359CF30FDD89AD00206180 /* DateConversion.h in Headers */ = {isa = PBXBuildFile; fileRef = D21202290AD4310C00ED79B6 /* DateConversion.h */; };
41359CF60FDD89CB00206180 /* DateMath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41359CF40FDD89CB00206180 /* DateMath.cpp */; };
- 41359CF70FDD89CB00206180 /* DateMath.h in Headers */ = {isa = PBXBuildFile; fileRef = 41359CF50FDD89CB00206180 /* DateMath.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 434A8E7114956A50009126F7 /* ASCIIFastPath.h in Headers */ = {isa = PBXBuildFile; fileRef = 434A8E7014956A50009126F7 /* ASCIIFastPath.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 4409D8470FAF80A200523B87 /* OwnPtrCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 440B7AED0FAF7FCB0073323E /* OwnPtrCommon.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 44DD48530FAEA85000D6B4EB /* PassOwnPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 44DD48520FAEA85000D6B4EB /* PassOwnPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
451539B912DC994500EF7AC4 /* Yarr.h in Headers */ = {isa = PBXBuildFile; fileRef = 451539B812DC994500EF7AC4 /* Yarr.h */; settings = {ATTRIBUTES = (Private, ); }; };
511FC4C9117EE28700425272 /* MD5.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 511FC4C7117EE23D00425272 /* MD5.cpp */; };
- 511FC4CB117EE2A800425272 /* MD5.h in Headers */ = {isa = PBXBuildFile; fileRef = 511FC4CA117EE2A800425272 /* MD5.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 5135FAF212D26ACE003C083B /* Decoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 5135FAD512D26856003C083B /* Decoder.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 5135FAF312D26AD1003C083B /* Encoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 5135FAD612D26856003C083B /* Encoder.h */; settings = {ATTRIBUTES = (Private, ); }; };
5D53726F0E1C54880021E549 /* Tracing.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D53726E0E1C54880021E549 /* Tracing.h */; };
5D5D8AD10E0D0EBE00F9C692 /* libedit.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 5D5D8AD00E0D0EBE00F9C692 /* libedit.dylib */; };
- 5D63E9AD10F2BD6E00FC8AE9 /* StringHasher.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D63E9AC10F2BD6E00FC8AE9 /* StringHasher.h */; settings = {ATTRIBUTES = (Private, ); }; };
5D6A566B0F05995500266145 /* Threading.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5D6A566A0F05995500266145 /* Threading.cpp */; };
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 */; };
@@ -383,21 +347,12 @@
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 */; };
- 651DCA04136A6FEF00F74194 /* PassTraits.h in Headers */ = {isa = PBXBuildFile; fileRef = 651DCA02136A6FAB00F74194 /* PassTraits.h */; settings = {ATTRIBUTES = (Private, ); }; };
65303D641447B9E100D3F904 /* ParserTokens.h in Headers */ = {isa = PBXBuildFile; fileRef = 65303D631447B9E100D3F904 /* ParserTokens.h */; settings = {ATTRIBUTES = (Private, ); }; };
655EB29B10CE2581001A990E /* NodesCodegen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 655EB29A10CE2581001A990E /* NodesCodegen.cpp */; };
65DFC93308EA173A00F7300B /* HashTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65DFC92D08EA173A00F7300B /* HashTable.cpp */; };
- 65E1A3DF122B894500B26097 /* NonCopyingSort.h in Headers */ = {isa = PBXBuildFile; fileRef = 65E1A2F4122B880D00B26097 /* NonCopyingSort.h */; settings = {ATTRIBUTES = (Private, ); }; };
65FDE49C0BDD1D4A00E80111 /* Assertions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65E217B808E7EECC0023E5F6 /* Assertions.cpp */; };
- 7186A6EC13100BA5004479E1 /* HexNumber.h in Headers */ = {isa = PBXBuildFile; fileRef = 7186A6E813100B57004479E1 /* HexNumber.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 71DA9D82134F3F3D00B767E7 /* StringOperators.h in Headers */ = {isa = PBXBuildFile; fileRef = 718A8482134F3A1200B87529 /* StringOperators.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 76FB9F0F12E851860051A2EB /* SHA1.h in Headers */ = {isa = PBXBuildFile; fileRef = 76FB9F0E12E851860051A2EB /* SHA1.h */; settings = {ATTRIBUTES = (Private, ); }; };
76FB9F1112E851960051A2EB /* SHA1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 76FB9F1012E851960051A2EB /* SHA1.cpp */; };
- 7934BB7B1361979300CB99A1 /* ParallelJobs.h in Headers */ = {isa = PBXBuildFile; fileRef = 7934BB761361979300CB99A1 /* ParallelJobs.h */; settings = {ATTRIBUTES = (Private, ); }; };
7934BB7C1361979400CB99A1 /* ParallelJobsGeneric.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7934BB771361979300CB99A1 /* ParallelJobsGeneric.cpp */; };
- 7934BB7D1361979400CB99A1 /* ParallelJobsGeneric.h in Headers */ = {isa = PBXBuildFile; fileRef = 7934BB781361979300CB99A1 /* ParallelJobsGeneric.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 7934BB7E1361979400CB99A1 /* ParallelJobsLibdispatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 7934BB791361979300CB99A1 /* ParallelJobsLibdispatch.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 7934BB7F1361979400CB99A1 /* ParallelJobsOpenMP.h in Headers */ = {isa = PBXBuildFile; fileRef = 7934BB7A1361979300CB99A1 /* ParallelJobsOpenMP.h */; settings = {ATTRIBUTES = (Private, ); }; };
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 */; };
@@ -409,16 +364,13 @@
8604F505143CE1C200B295F5 /* JSGlobalThis.h in Headers */ = {isa = PBXBuildFile; fileRef = 8604F503143CE1C100B295F5 /* JSGlobalThis.h */; settings = {ATTRIBUTES = (Private, ); }; };
860BD801148EA6F200112B2F /* Intrinsic.h in Headers */ = {isa = PBXBuildFile; fileRef = 86BF642A148DB2B5004DE36A /* Intrinsic.h */; settings = {ATTRIBUTES = (Private, ); }; };
8626BECF11928E3900782FAB /* StringStatics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8626BECE11928E3900782FAB /* StringStatics.cpp */; };
- 8627E5EC11F1281900A313B5 /* PageAllocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 8627E5EA11F1281900A313B5 /* PageAllocation.h */; settings = {ATTRIBUTES = (Private, ); }; };
863B23E00FC6118900703AA4 /* MacroAssemblerCodeRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 863B23DF0FC60E6200703AA4 /* MacroAssemblerCodeRef.h */; settings = {ATTRIBUTES = (Private, ); }; };
86438FC41265503E00E0DFCA /* StringBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86438FC31265503E00E0DFCA /* StringBuilder.cpp */; };
86565742115BE3DA00291F40 /* CString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86565740115BE3DA00291F40 /* CString.cpp */; };
- 86565743115BE3DA00291F40 /* CString.h in Headers */ = {isa = PBXBuildFile; fileRef = 86565741115BE3DA00291F40 /* CString.h */; settings = {ATTRIBUTES = (Private, ); }; };
865A30F1135007E100CDB49E /* JSValueInlineMethods.h in Headers */ = {isa = PBXBuildFile; fileRef = 865A30F0135007E100CDB49E /* JSValueInlineMethods.h */; settings = {ATTRIBUTES = (Private, ); }; };
865F408810E7D56300947361 /* APIShims.h in Headers */ = {isa = PBXBuildFile; fileRef = 865F408710E7D56300947361 /* APIShims.h */; settings = {ATTRIBUTES = (Private, ); }; };
866739D213BFDE710023D87C /* BigInteger.h in Headers */ = {isa = PBXBuildFile; fileRef = 866739D013BFDE710023D87C /* BigInteger.h */; };
866739D313BFDE710023D87C /* Uint16WithFraction.h in Headers */ = {isa = PBXBuildFile; fileRef = 866739D113BFDE710023D87C /* Uint16WithFraction.h */; };
- 86676D5211FED9BC004B6863 /* BumpPointerAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 86676D4D11FED55D004B6863 /* BumpPointerAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
86704B4212DB8A8100A9FE7B /* YarrSyntaxChecker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86704B4012DB8A8100A9FE7B /* YarrSyntaxChecker.cpp */; };
86704B4312DB8A8100A9FE7B /* YarrSyntaxChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = 86704B4112DB8A8100A9FE7B /* YarrSyntaxChecker.h */; };
86704B8412DBA33700A9FE7B /* YarrInterpreter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86704B7D12DBA33700A9FE7B /* YarrInterpreter.cpp */; };
@@ -431,15 +383,8 @@
86880F1F14328BB900B08D42 /* DFGSpeculativeJIT32_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86880F1B14328BB900B08D42 /* DFGSpeculativeJIT32_64.cpp */; };
86880F4D14353B2100B08D42 /* DFGSpeculativeJIT64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86880F4C14353B2100B08D42 /* DFGSpeculativeJIT64.cpp */; };
868BFA08117CEFD100B908B1 /* AtomicString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 868BFA00117CEFD100B908B1 /* AtomicString.cpp */; };
- 868BFA09117CEFD100B908B1 /* AtomicString.h in Headers */ = {isa = PBXBuildFile; fileRef = 868BFA01117CEFD100B908B1 /* AtomicString.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 868BFA0A117CEFD100B908B1 /* AtomicStringImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 868BFA02117CEFD100B908B1 /* AtomicStringImpl.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 868BFA0D117CEFD100B908B1 /* StringHash.h in Headers */ = {isa = PBXBuildFile; fileRef = 868BFA05117CEFD100B908B1 /* StringHash.h */; settings = {ATTRIBUTES = (Private, ); }; };
868BFA0E117CEFD100B908B1 /* StringImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 868BFA06117CEFD100B908B1 /* StringImpl.cpp */; };
- 868BFA0F117CEFD100B908B1 /* StringImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 868BFA07117CEFD100B908B1 /* StringImpl.h */; settings = {ATTRIBUTES = (Private, ); }; };
868BFA17117CF19900B908B1 /* WTFString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 868BFA15117CF19900B908B1 /* WTFString.cpp */; };
- 868BFA18117CF19900B908B1 /* WTFString.h in Headers */ = {isa = PBXBuildFile; fileRef = 868BFA16117CF19900B908B1 /* WTFString.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 868BFA60117D048200B908B1 /* StaticConstructors.h in Headers */ = {isa = PBXBuildFile; fileRef = 868BFA5F117D048200B908B1 /* StaticConstructors.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 8690231512092D5C00630AF9 /* PageReservation.h in Headers */ = {isa = PBXBuildFile; fileRef = 8690231412092D5C00630AF9 /* PageReservation.h */; settings = {ATTRIBUTES = (Private, ); }; };
869D04AF1193B54D00803475 /* CachedTranscendentalFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 869D04AE1193B54D00803475 /* CachedTranscendentalFunction.h */; settings = {ATTRIBUTES = (Private, ); }; };
869EBCB70E8C6D4A008722CC /* ResultType.h in Headers */ = {isa = PBXBuildFile; fileRef = 869EBCB60E8C6D4A008722CC /* ResultType.h */; settings = {ATTRIBUTES = (Private, ); }; };
86A90ED00EE7D51F00AB350D /* JITArithmetic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86A90ECF0EE7D51F00AB350D /* JITArithmetic.cpp */; };
@@ -452,7 +397,6 @@
86AE6C4E136A11E400963012 /* DFGGPRInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 86AE6C4C136A11E400963012 /* DFGGPRInfo.h */; };
86B5826714D2796C00A9C306 /* CodeProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86B5822E14D2373B00A9C306 /* CodeProfile.cpp */; };
86B5826914D2797000A9C306 /* CodeProfiling.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8603CEF214C7546400AE59E3 /* CodeProfiling.cpp */; };
- 86B99AE3117E578100DF5A90 /* StringBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 86B99AE1117E578100DF5A90 /* StringBuffer.h */; settings = {ATTRIBUTES = (Private, ); }; };
86BB09C0138E381B0056702F /* DFGRepatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86BB09BE138E381B0056702F /* DFGRepatch.cpp */; };
86BB09C1138E381B0056702F /* DFGRepatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 86BB09BF138E381B0056702F /* DFGRepatch.h */; };
86C36EEA0EE1289D00B3DF59 /* MacroAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C36EE90EE1289D00B3DF59 /* MacroAssembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -466,7 +410,6 @@
86CC85C40EE7A89400288682 /* JITPropertyAccess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86CC85C30EE7A89400288682 /* JITPropertyAccess.cpp */; };
86CCEFDE0F413F8900FD7F9E /* JITCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 86CCEFDD0F413F8900FD7F9E /* JITCode.h */; settings = {ATTRIBUTES = (Private, ); }; };
86D08D5311793613006E5ED0 /* WTFThreadData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86D08D5111793613006E5ED0 /* WTFThreadData.cpp */; };
- 86D08D5411793613006E5ED0 /* WTFThreadData.h in Headers */ = {isa = PBXBuildFile; fileRef = 86D08D5211793613006E5ED0 /* WTFThreadData.h */; settings = {ATTRIBUTES = (Private, ); }; };
86D3B2C310156BDE002865E7 /* ARMAssembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86D3B2BF10156BDE002865E7 /* ARMAssembler.cpp */; };
86D3B2C410156BDE002865E7 /* ARMAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86D3B2C010156BDE002865E7 /* ARMAssembler.h */; };
86D3B2C510156BDE002865E7 /* AssemblerBufferWithConstantPool.h in Headers */ = {isa = PBXBuildFile; fileRef = 86D3B2C110156BDE002865E7 /* AssemblerBufferWithConstantPool.h */; };
@@ -474,7 +417,6 @@
86D3B3C310159D7F002865E7 /* LinkBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 86D3B3C110159D7F002865E7 /* LinkBuffer.h */; };
86D3B3C410159D7F002865E7 /* RepatchBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 86D3B3C210159D7F002865E7 /* RepatchBuffer.h */; };
86D87DAE12BCA7D1008E73A1 /* StackBounds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86D87DA512BC4B14008E73A1 /* StackBounds.cpp */; };
- 86D87DDB12BCAF94008E73A1 /* StackBounds.h in Headers */ = {isa = PBXBuildFile; fileRef = 86D87DA612BC4B14008E73A1 /* StackBounds.h */; settings = {ATTRIBUTES = (Private, ); }; };
86DB64640F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86DB64630F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp */; };
86E116B10FE75AC800B512BC /* CodeLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 86E116B00FE75AC800B512BC /* CodeLocation.h */; };
86E85539111B9968001AF51E /* JSStringBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 86E85538111B9968001AF51E /* JSStringBuilder.h */; };
@@ -492,14 +434,11 @@
86EC9DD31328DF82002B2AD7 /* DFGSpeculativeJIT.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EC9DC31328DF82002B2AD7 /* DFGSpeculativeJIT.h */; };
86ECA3EA132DEF1C002B2AD7 /* DFGNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 86ECA3E9132DEF1C002B2AD7 /* DFGNode.h */; };
86ECA3FA132DF25A002B2AD7 /* DFGScoreBoard.h in Headers */ = {isa = PBXBuildFile; fileRef = 86ECA3F9132DF25A002B2AD7 /* DFGScoreBoard.h */; };
- 86F38859121130CA007A7CE3 /* AtomicStringHash.h in Headers */ = {isa = PBXBuildFile; fileRef = 86F38858121130CA007A7CE3 /* AtomicStringHash.h */; settings = {ATTRIBUTES = (Private, ); }; };
86FA9E91142BBB2E001773B7 /* JSBoundFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86FA9E8F142BBB2D001773B7 /* JSBoundFunction.cpp */; };
86FA9E92142BBB2E001773B7 /* JSBoundFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 86FA9E90142BBB2E001773B7 /* JSBoundFunction.h */; };
90213E3D123A40C200D422F3 /* MemoryStatistics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90213E3B123A40C200D422F3 /* MemoryStatistics.cpp */; };
90213E3E123A40C200D422F3 /* MemoryStatistics.h in Headers */ = {isa = PBXBuildFile; fileRef = 90213E3C123A40C200D422F3 /* MemoryStatistics.h */; settings = {ATTRIBUTES = (Private, ); }; };
905B02AE0E28640F006DF882 /* RefCountedLeakCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 905B02AD0E28640F006DF882 /* RefCountedLeakCounter.cpp */; };
- 90D3469C0E285280009492EE /* RefCountedLeakCounter.h in Headers */ = {isa = PBXBuildFile; fileRef = 90D3469B0E285280009492EE /* RefCountedLeakCounter.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 91A3905614C0F47200F67901 /* Uint8ClampedArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 91A3905514C0F47200F67901 /* Uint8ClampedArray.h */; settings = {ATTRIBUTES = (Private, ); }; };
93052C340FB792190048FDC3 /* ParserArena.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93052C320FB792190048FDC3 /* ParserArena.cpp */; };
93052C350FB792190048FDC3 /* ParserArena.h in Headers */ = {isa = PBXBuildFile; fileRef = 93052C330FB792190048FDC3 /* ParserArena.h */; settings = {ATTRIBUTES = (Private, ); }; };
932F5BD30822A1C700736975 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6560A4CF04B3B3E7008AE952 /* CoreFoundation.framework */; };
@@ -510,7 +449,6 @@
933040040E6A749400786E6A /* SmallStrings.h in Headers */ = {isa = PBXBuildFile; fileRef = 93303FEA0E6A72C000786E6A /* SmallStrings.h */; settings = {ATTRIBUTES = (Private, ); }; };
9330402C0E6A764000786E6A /* SmallStrings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93303FE80E6A72B500786E6A /* SmallStrings.cpp */; };
9335F24D12E6765B002B5553 /* StringRecursionChecker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93345A8712D838C400302BE3 /* StringRecursionChecker.cpp */; };
- 933F5CDC1269229B0049191E /* NullPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 933F5CDB126922690049191E /* NullPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
93854A9A12C93D3B00DAAF77 /* NullPtr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93854A9912C93D3B00DAAF77 /* NullPtr.cpp */; };
9534AAFB0E5B7A9600B8A45B /* JSProfilerPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 952C63AC0E4777D600C13936 /* JSProfilerPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
95742F650DD11F5A000917FB /* Profile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95742F630DD11F5A000917FB /* Profile.cpp */; };
@@ -527,25 +465,20 @@
969A07230ED1CE3300F1F681 /* BytecodeGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 969A07210ED1CE3300F1F681 /* BytecodeGenerator.h */; };
969A072A0ED1CE6900F1F681 /* Label.h in Headers */ = {isa = PBXBuildFile; fileRef = 969A07270ED1CE6900F1F681 /* Label.h */; };
969A072B0ED1CE6900F1F681 /* RegisterID.h in Headers */ = {isa = PBXBuildFile; fileRef = 969A07280ED1CE6900F1F681 /* RegisterID.h */; };
- 969A072C0ED1CE6900F1F681 /* SegmentedVector.h in Headers */ = {isa = PBXBuildFile; fileRef = 969A07290ED1CE6900F1F681 /* SegmentedVector.h */; settings = {ATTRIBUTES = (Private, ); }; };
969A07960ED1D3AE00F1F681 /* CodeBlock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 969A07900ED1D3AE00F1F681 /* CodeBlock.cpp */; settings = {COMPILER_FLAGS = "-fno-strict-aliasing"; }; };
969A07970ED1D3AE00F1F681 /* CodeBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 969A07910ED1D3AE00F1F681 /* CodeBlock.h */; settings = {ATTRIBUTES = (); }; };
969A07980ED1D3AE00F1F681 /* EvalCodeCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 969A07920ED1D3AE00F1F681 /* EvalCodeCache.h */; };
969A07990ED1D3AE00F1F681 /* Instruction.h in Headers */ = {isa = PBXBuildFile; fileRef = 969A07930ED1D3AE00F1F681 /* Instruction.h */; };
969A079A0ED1D3AE00F1F681 /* Opcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 969A07940ED1D3AE00F1F681 /* Opcode.cpp */; };
969A079B0ED1D3AE00F1F681 /* Opcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 969A07950ED1D3AE00F1F681 /* Opcode.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 96DD73790F9DA3100027FBCC /* VMTags.h in Headers */ = {isa = PBXBuildFile; fileRef = 96DD73780F9DA3100027FBCC /* VMTags.h */; settings = {ATTRIBUTES = (Private, ); }; };
971EDEA61169E0D3005E4262 /* Terminator.h in Headers */ = {isa = PBXBuildFile; fileRef = 97F6903A1169DF7F00A6BB46 /* Terminator.h */; settings = {ATTRIBUTES = (Private, ); }; };
978801401471AD920041B016 /* JSDateMath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9788FC221471AD0C0068CE2D /* JSDateMath.cpp */; };
978801411471AD920041B016 /* JSDateMath.h in Headers */ = {isa = PBXBuildFile; fileRef = 9788FC231471AD0C0068CE2D /* JSDateMath.h */; settings = {ATTRIBUTES = (Private, ); }; };
97941A5713029AAB004A3447 /* OSRandomSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97941A3F130299DB004A3447 /* OSRandomSource.cpp */; };
- 97941A5A13029ACC004A3447 /* OSRandomSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 97941A40130299DB004A3447 /* OSRandomSource.h */; };
97941A7E1302A098004A3447 /* CryptographicallyRandomNumber.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97941A7C1302A098004A3447 /* CryptographicallyRandomNumber.cpp */; };
- 97941A7F1302A098004A3447 /* CryptographicallyRandomNumber.h in Headers */ = {isa = PBXBuildFile; fileRef = 97941A7D1302A098004A3447 /* CryptographicallyRandomNumber.h */; settings = {ATTRIBUTES = (Private, ); }; };
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, ); }; };
- A1D764521354448B00C5C7C0 /* Alignment.h in Headers */ = {isa = PBXBuildFile; fileRef = A1D764511354448B00C5C7C0 /* Alignment.h */; settings = {ATTRIBUTES = (Private, ); }; };
A71236E51195F33C00BD2174 /* JITOpcodes32_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A71236E41195F33C00BD2174 /* JITOpcodes32_64.cpp */; };
A72700900DAC6BBC00E548D7 /* JSNotAnObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A72700780DAC605600E548D7 /* JSNotAnObject.cpp */; };
A72701B90DADE94900E548D7 /* ExceptionHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = A72701B30DADE94900E548D7 /* ExceptionHelpers.h */; };
@@ -559,19 +492,7 @@
A7386555118697B400540279 /* ThunkGenerators.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7386552118697B400540279 /* ThunkGenerators.cpp */; };
A7386556118697B400540279 /* ThunkGenerators.h in Headers */ = {isa = PBXBuildFile; fileRef = A7386553118697B400540279 /* ThunkGenerators.h */; settings = {ATTRIBUTES = (Private, ); }; };
A73BE168148420520091204B /* ArrayBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A73BE154148420520091204B /* ArrayBuffer.cpp */; };
- A73BE169148420520091204B /* ArrayBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = A73BE155148420520091204B /* ArrayBuffer.h */; settings = {ATTRIBUTES = (Private, ); }; };
A73BE16A148420520091204B /* ArrayBufferView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A73BE156148420520091204B /* ArrayBufferView.cpp */; };
- A73BE16B148420520091204B /* ArrayBufferView.h in Headers */ = {isa = PBXBuildFile; fileRef = A73BE157148420520091204B /* ArrayBufferView.h */; settings = {ATTRIBUTES = (Private, ); }; };
- A73BE16D148420520091204B /* Float32Array.h in Headers */ = {isa = PBXBuildFile; fileRef = A73BE159148420520091204B /* Float32Array.h */; settings = {ATTRIBUTES = (Private, ); }; };
- A73BE16F148420520091204B /* Float64Array.h in Headers */ = {isa = PBXBuildFile; fileRef = A73BE15B148420520091204B /* Float64Array.h */; settings = {ATTRIBUTES = (Private, ); }; };
- A73BE171148420520091204B /* Int8Array.h in Headers */ = {isa = PBXBuildFile; fileRef = A73BE15D148420520091204B /* Int8Array.h */; settings = {ATTRIBUTES = (Private, ); }; };
- A73BE173148420520091204B /* Int16Array.h in Headers */ = {isa = PBXBuildFile; fileRef = A73BE15F148420520091204B /* Int16Array.h */; settings = {ATTRIBUTES = (Private, ); }; };
- A73BE175148420520091204B /* Int32Array.h in Headers */ = {isa = PBXBuildFile; fileRef = A73BE161148420520091204B /* Int32Array.h */; settings = {ATTRIBUTES = (Private, ); }; };
- A73BE177148420520091204B /* Uint8Array.h in Headers */ = {isa = PBXBuildFile; fileRef = A73BE163148420520091204B /* Uint8Array.h */; settings = {ATTRIBUTES = (Private, ); }; };
- A73BE179148420520091204B /* Uint16Array.h in Headers */ = {isa = PBXBuildFile; fileRef = A73BE165148420520091204B /* Uint16Array.h */; settings = {ATTRIBUTES = (Private, ); }; };
- A73BE17B148420520091204B /* Uint32Array.h in Headers */ = {isa = PBXBuildFile; fileRef = A73BE167148420520091204B /* Uint32Array.h */; settings = {ATTRIBUTES = (Private, ); }; };
- A73BE17E148420840091204B /* TypedArrayBase.h in Headers */ = {isa = PBXBuildFile; fileRef = A73BE17D148420840091204B /* TypedArrayBase.h */; settings = {ATTRIBUTES = (Private, ); }; };
- A73BE180148420A80091204B /* IntegralTypedArrayBase.h in Headers */ = {isa = PBXBuildFile; fileRef = A73BE17F148420A80091204B /* IntegralTypedArrayBase.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, ); }; };
@@ -587,24 +508,16 @@
A791EF280F11E07900AE1F68 /* JSByteArray.h in Headers */ = {isa = PBXBuildFile; fileRef = A791EF260F11E07900AE1F68 /* JSByteArray.h */; settings = {ATTRIBUTES = (Private, ); }; };
A791EF290F11E07900AE1F68 /* JSByteArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A791EF270F11E07900AE1F68 /* JSByteArray.cpp */; };
A7A1F7AC0F252B3C00E184E2 /* ByteArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7A1F7AA0F252B3C00E184E2 /* ByteArray.cpp */; };
- A7A1F7AD0F252B3C00E184E2 /* ByteArray.h in Headers */ = {isa = PBXBuildFile; fileRef = A7A1F7AB0F252B3C00E184E2 /* ByteArray.h */; settings = {ATTRIBUTES = (Private, ); }; };
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, ); }; };
- A7BC0C82140608B000B1BB71 /* CheckedArithmetic.h in Headers */ = {isa = PBXBuildFile; fileRef = A7BC0C81140608B000B1BB71 /* CheckedArithmetic.h */; settings = {ATTRIBUTES = (Private, ); }; };
A7C1E8E4112E72EF00A37F98 /* JITPropertyAccess32_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7C1E8C8112E701C00A37F98 /* JITPropertyAccess32_64.cpp */; };
- A7C40C0A130B057D00D002A1 /* BlockStack.h in Headers */ = {isa = PBXBuildFile; fileRef = A7C40C07130B057D00D002A1 /* BlockStack.h */; settings = {ATTRIBUTES = (Private, ); }; };
- A7C40C0B130B057D00D002A1 /* SentinelLinkedList.h in Headers */ = {isa = PBXBuildFile; fileRef = A7C40C08130B057D00D002A1 /* SentinelLinkedList.h */; settings = {ATTRIBUTES = (Private, ); }; };
- A7C40C0C130B057D00D002A1 /* SinglyLinkedList.h in Headers */ = {isa = PBXBuildFile; fileRef = A7C40C09130B057D00D002A1 /* SinglyLinkedList.h */; settings = {ATTRIBUTES = (Private, ); }; };
- A7D649AA1015224E009B2E1B /* PossiblyNull.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D649A91015224E009B2E1B /* PossiblyNull.h */; settings = {ATTRIBUTES = (Private, ); }; };
A7DCB97312E5193F00911940 /* WriteBarrier.h in Headers */ = {isa = PBXBuildFile; fileRef = A7DCB77912E3D90500911940 /* WriteBarrier.h */; settings = {ATTRIBUTES = (Private, ); }; };
A7E2EA6B0FB460CF00601F06 /* LiteralParser.h in Headers */ = {isa = PBXBuildFile; fileRef = A7E2EA690FB460CF00601F06 /* LiteralParser.h */; };
A7E2EA6C0FB460CF00601F06 /* LiteralParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7E2EA6A0FB460CF00601F06 /* LiteralParser.cpp */; };
- A7F19ECE11DD490900931E70 /* FixedArray.h in Headers */ = {isa = PBXBuildFile; fileRef = A7F19ECD11DD490900931E70 /* FixedArray.h */; settings = {ATTRIBUTES = (Private, ); }; };
A7F9935F0FD7325100A0B2D0 /* JSONObject.h in Headers */ = {isa = PBXBuildFile; fileRef = A7F9935D0FD7325100A0B2D0 /* JSONObject.h */; };
A7F993600FD7325100A0B2D0 /* JSONObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7F9935E0FD7325100A0B2D0 /* JSONObject.cpp */; };
A7FB60A4103F7DC20017A286 /* PropertyDescriptor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7FB60A3103F7DC20017A286 /* PropertyDescriptor.cpp */; };
A7FB61001040C38B0017A286 /* PropertyDescriptor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7FB604B103F5EAB0017A286 /* PropertyDescriptor.h */; settings = {ATTRIBUTES = (Private, ); }; };
- A7FEE67614837B32005DC1A6 /* ExportMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = A7A275F514837A8E001DBB39 /* ExportMacros.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC02E90D0E1839DB000F9297 /* ErrorConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BC02E9050E1839DB000F9297 /* ErrorConstructor.h */; };
BC02E90F0E1839DB000F9297 /* ErrorPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = BC02E9070E1839DB000F9297 /* ErrorPrototype.h */; };
BC02E9110E1839DB000F9297 /* NativeErrorConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BC02E9090E1839DB000F9297 /* NativeErrorConstructor.h */; };
@@ -613,38 +526,20 @@
BC1166020E1997B4008066DD /* DateInstance.h in Headers */ = {isa = PBXBuildFile; fileRef = BC1166010E1997B1008066DD /* DateInstance.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC11667B0E199C05008066DD /* InternalFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = BC11667A0E199C05008066DD /* InternalFunction.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC1167DA0E19BCC9008066DD /* JSCell.h in Headers */ = {isa = PBXBuildFile; fileRef = BC1167D80E19BCC9008066DD /* JSCell.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C3E40E16F5CD00B34460 /* AlwaysInline.h in Headers */ = {isa = PBXBuildFile; fileRef = 93AA4F770957251F0084B3A7 /* AlwaysInline.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C3E50E16F5CD00B34460 /* APICast.h in Headers */ = {isa = PBXBuildFile; fileRef = 1482B78A0A4305AB00517CFC /* APICast.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C3E60E16F5CD00B34460 /* ArrayConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BC7952070E15E8A800A898AB /* ArrayConstructor.h */; };
BC18C3E70E16F5CD00B34460 /* ArrayPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A84E0255597D01FF60F7 /* ArrayPrototype.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C3E90E16F5CD00B34460 /* ASCIICType.h in Headers */ = {isa = PBXBuildFile; fileRef = 938C4F690CA06BC700D9310A /* ASCIICType.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C3EA0E16F5CD00B34460 /* Assertions.h in Headers */ = {isa = PBXBuildFile; fileRef = 65E217B708E7EECC0023E5F6 /* Assertions.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C3EB0E16F5CD00B34460 /* AVLTree.h in Headers */ = {isa = PBXBuildFile; fileRef = E1A596370DE3E1C300C17E37 /* AVLTree.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C3EC0E16F5CD00B34460 /* BooleanObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 704FD35305697E6D003DBED9 /* BooleanObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C3ED0E16F5CD00B34460 /* CallData.h in Headers */ = {isa = PBXBuildFile; fileRef = 145C507F0D9DF63B0088F6B9 /* CallData.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C3F00E16F5CD00B34460 /* Collator.h in Headers */ = {isa = PBXBuildFile; fileRef = E1A862AA0D7EBB7D001EC6AA /* Collator.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C3F30E16F5CD00B34460 /* CommonIdentifiers.h in Headers */ = {isa = PBXBuildFile; fileRef = 65EA73630BAE35D1001BB560 /* CommonIdentifiers.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C3F40E16F5CD00B34460 /* Completion.h in Headers */ = {isa = PBXBuildFile; fileRef = F5BB2BC5030F772101FCFE1D /* Completion.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C3F50E16F5CD00B34460 /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = F68EBB8C0255D4C601FF60F7 /* config.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C3F60E16F5CD00B34460 /* ConstructData.h in Headers */ = {isa = PBXBuildFile; fileRef = BC8F3CCF0DAF17BA00577A80 /* ConstructData.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C3FA0E16F5CD00B34460 /* Debugger.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8590255597D01FF60F7 /* Debugger.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C3FB0E16F5CD00B34460 /* DebuggerCallFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 1480DB9B0DDC227F003CFDF2 /* DebuggerCallFrame.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C3FC0E16F5CD00B34460 /* Deque.h in Headers */ = {isa = PBXBuildFile; fileRef = 5186111D0CC824830081412B /* Deque.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C3FD0E16F5CD00B34460 /* DisallowCType.h in Headers */ = {isa = PBXBuildFile; fileRef = 938C4F6B0CA06BCE00D9310A /* DisallowCType.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C3FE0E16F5CD00B34460 /* dtoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 651F6413039D5B5F0078395C /* dtoa.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4000E16F5CD00B34460 /* ExceptionHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = A72701B30DADE94900E548D7 /* ExceptionHelpers.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C4020E16F5CD00B34460 /* FastMalloc.h in Headers */ = {isa = PBXBuildFile; fileRef = 65E217BA08E7EECC0023E5F6 /* FastMalloc.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C4030E16F5CD00B34460 /* Forward.h in Headers */ = {isa = PBXBuildFile; fileRef = 935AF46909E9D9DB00ACD1D8 /* Forward.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4040E16F5CD00B34460 /* FunctionConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BC2680C10E16D4E900A06E92 /* FunctionConstructor.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4050E16F5CD00B34460 /* FunctionPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A85D0255597D01FF60F7 /* FunctionPrototype.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C4060E16F5CD00B34460 /* GetPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 93B6A0DE0AA64DA40076DE27 /* GetPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C4080E16F5CD00B34460 /* HashCountedSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 657EEBBF094E445E008C9C7B /* HashCountedSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C4090E16F5CD00B34460 /* HashFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 65DFC92A08EA173A00F7300B /* HashFunctions.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C40A0E16F5CD00B34460 /* HashIterators.h in Headers */ = {isa = PBXBuildFile; fileRef = 652246A40C8D7A0E007BDAF7 /* HashIterators.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C40B0E16F5CD00B34460 /* HashMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 65DFC92B08EA173A00F7300B /* HashMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C40C0E16F5CD00B34460 /* HashSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 65DFC92C08EA173A00F7300B /* HashSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C40D0E16F5CD00B34460 /* HashTable.h in Headers */ = {isa = PBXBuildFile; fileRef = 65DFC92E08EA173A00F7300B /* HashTable.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C40E0E16F5CD00B34460 /* HashTraits.h in Headers */ = {isa = PBXBuildFile; fileRef = 65DFC92F08EA173A00F7300B /* HashTraits.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C40F0E16F5CD00B34460 /* Identifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 933A349A038AE7C6008635CE /* Identifier.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4100E16F5CD00B34460 /* InitializeThreading.h in Headers */ = {isa = PBXBuildFile; fileRef = E178633F0D9BEC0000D74E75 /* InitializeThreading.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4130E16F5CD00B34460 /* JavaScript.h in Headers */ = {isa = PBXBuildFile; fileRef = 1CAA8B4A0D32C39A0041BCFF /* JavaScript.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -675,17 +570,9 @@
BC18C42D0E16F5CD00B34460 /* JSVariableObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 14F252560D08DD8D004ECFFF /* JSVariableObject.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 */; };
- BC18C4340E16F5CD00B34460 /* ListHashSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 657EB7450B708F540063461B /* ListHashSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C4350E16F5CD00B34460 /* ListRefPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 148A1626095D16BB00666D0D /* ListRefPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C4360E16F5CD00B34460 /* Locker.h in Headers */ = {isa = PBXBuildFile; fileRef = E1EE79270D6C964500FEA3BA /* Locker.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4370E16F5CD00B34460 /* Lookup.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8690255597D01FF60F7 /* Lookup.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C4390E16F5CD00B34460 /* MainThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 06D358A30DAAD9C4003B174E /* MainThread.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C43A0E16F5CD00B34460 /* MallocZoneSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DBD18AF0C5401A700C15EAE /* MallocZoneSupport.h */; settings = {ATTRIBUTES = (); }; };
- BC18C43B0E16F5CD00B34460 /* MathExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = BCF6553B0A2048DE0038A194 /* MathExtras.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C43C0E16F5CD00B34460 /* MathObject.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A86B0255597D01FF60F7 /* MathObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C43E0E16F5CD00B34460 /* MessageQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = E1EE798B0D6CA53D00FEA3BA /* MessageQueue.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C43F0E16F5CD00B34460 /* Nodes.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A86E0255597D01FF60F7 /* Nodes.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C4400E16F5CD00B34460 /* Noncopyable.h in Headers */ = {isa = PBXBuildFile; fileRef = 9303F5690991190000AD71B8 /* Noncopyable.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4410E16F5CD00B34460 /* NumberConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BC2680C30E16D4E900A06E92 /* NumberConstructor.h */; };
BC18C4420E16F5CD00B34460 /* NumberConstructor.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = BC2680E60E16D52300A06E92 /* NumberConstructor.lut.h */; };
BC18C4430E16F5CD00B34460 /* NumberObject.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8710255597D01FF60F7 /* NumberObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -693,46 +580,25 @@
BC18C4450E16F5CD00B34460 /* ObjectConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BC2680C70E16D4E900A06E92 /* ObjectConstructor.h */; };
BC18C4460E16F5CD00B34460 /* ObjectPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = BC2680C90E16D4E900A06E92 /* ObjectPrototype.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4480E16F5CD00B34460 /* Operations.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8780255597D01FF60F7 /* Operations.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C4490E16F5CD00B34460 /* OwnArrayPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 9303F5A409911A5800AD71B8 /* OwnArrayPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C44A0E16F5CD00B34460 /* OwnPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 9303F567099118FA00AD71B8 /* OwnPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C44B0E16F5CD00B34460 /* Parser.h in Headers */ = {isa = PBXBuildFile; fileRef = 93F0B3AA09BB4DC00068FCE3 /* Parser.h */; settings = {ATTRIBUTES = (); }; };
- BC18C44C0E16F5CD00B34460 /* PassRefPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 6580F795094070560082C219 /* PassRefPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C44F0E16F5CD00B34460 /* Platform.h in Headers */ = {isa = PBXBuildFile; fileRef = 65D6D87E09B5A32E0002E4D7 /* Platform.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4500E16F5CD00B34460 /* Profile.h in Headers */ = {isa = PBXBuildFile; fileRef = 95742F640DD11F5A000917FB /* Profile.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4510E16F5CD00B34460 /* ProfileNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 95AB83550DA43B4400BC83F3 /* ProfileNode.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4520E16F5CD00B34460 /* Profiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 95AB832F0DA42CAD00BC83F3 /* Profiler.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4540E16F5CD00B34460 /* PropertyNameArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 65400C100A69BAF200509887 /* PropertyNameArray.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4550E16F5CD00B34460 /* PropertySlot.h in Headers */ = {isa = PBXBuildFile; fileRef = 65621E6C089E859700760F35 /* PropertySlot.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4560E16F5CD00B34460 /* Protect.h in Headers */ = {isa = PBXBuildFile; fileRef = 65C02FBB0637462A003E7EE6 /* Protect.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C4570E16F5CD00B34460 /* RefCounted.h in Headers */ = {isa = PBXBuildFile; fileRef = 1419D32C0CEA7CDE00FF507A /* RefCounted.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C4580E16F5CD00B34460 /* RefPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 65C647B3093EF8D60022C380 /* RefPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C4590E16F5CD00B34460 /* RefPtrHashMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 148A1ECD0D10C23B0069A47C /* RefPtrHashMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C45A0E16F5CD00B34460 /* RegExp.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A87E0255597D01FF60F7 /* RegExp.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C45B0E16F5CD00B34460 /* RegExpObject.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A87C0255597D01FF60F7 /* RegExpObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C45D0E16F5CD00B34460 /* Register.h in Headers */ = {isa = PBXBuildFile; fileRef = 149B24FF0D8AF6D1009CB8C7 /* Register.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C45E0E16F5CD00B34460 /* RegisterFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 14D792640DAA03FB001A9F05 /* RegisterFile.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C4600E16F5CD00B34460 /* RetainPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 51F648D60BB4E2CA0033D760 /* RetainPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4610E16F5CD00B34460 /* ScopeChain.h in Headers */ = {isa = PBXBuildFile; fileRef = 9374D3A7038D9D74008635CE /* ScopeChain.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4630E16F5CD00B34460 /* SourceProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 65E866ED0DD59AFA00A2B2A1 /* SourceProvider.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4640E16F5CD00B34460 /* SourceCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 65E866EE0DD59AFA00A2B2A1 /* SourceCode.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4660E16F5CD00B34460 /* StringConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BC18C3C10E16EE3300B34460 /* StringConstructor.h */; };
- BC18C4670E16F5CD00B34460 /* StringExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = E11D51750B2E798D0056C188 /* StringExtras.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4680E16F5CD00B34460 /* StringObject.h in Headers */ = {isa = PBXBuildFile; fileRef = BC18C3C30E16EE3300B34460 /* StringObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C46A0E16F5CD00B34460 /* StringPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = BC18C3C60E16EE3300B34460 /* StringPrototype.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C46B0E16F5CD00B34460 /* SymbolTable.h in Headers */ = {isa = PBXBuildFile; fileRef = 14A396A60CD2933100B5B4FF /* SymbolTable.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C46C0E16F5CD00B34460 /* TCPackedCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DA479650CFBCF56009328A0 /* TCPackedCache.h */; };
- BC18C46D0E16F5CD00B34460 /* TCPageMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 6541BD6E08E80A17002CBEE7 /* TCPageMap.h */; };
- BC18C46E0E16F5CD00B34460 /* TCSpinLock.h in Headers */ = {isa = PBXBuildFile; fileRef = 6541BD6F08E80A17002CBEE7 /* TCSpinLock.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C46F0E16F5CD00B34460 /* TCSystemAlloc.h in Headers */ = {isa = PBXBuildFile; fileRef = 6541BD7108E80A17002CBEE7 /* TCSystemAlloc.h */; };
- BC18C4700E16F5CD00B34460 /* Threading.h in Headers */ = {isa = PBXBuildFile; fileRef = E1EE79220D6C95CD00FEA3BA /* Threading.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C4710E16F5CD00B34460 /* ThreadSpecific.h in Headers */ = {isa = PBXBuildFile; fileRef = E1B7C8BD0DA3A3360074B0DC /* ThreadSpecific.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C4730E16F5CD00B34460 /* Unicode.h in Headers */ = {isa = PBXBuildFile; fileRef = E195679409E7CF1200B89D13 /* Unicode.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C4740E16F5CD00B34460 /* UnicodeIcu.h in Headers */ = {isa = PBXBuildFile; fileRef = E195678F09E7CF1200B89D13 /* UnicodeIcu.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C4750E16F5CD00B34460 /* UnusedParam.h in Headers */ = {isa = PBXBuildFile; fileRef = 935AF46B09E9D9DB00ACD1D8 /* UnusedParam.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4760E16F5CD00B34460 /* UString.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8860255597D01FF60F7 /* UString.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C4770E16F5CD00B34460 /* UTF8.h in Headers */ = {isa = PBXBuildFile; fileRef = E1EF79A90CE97BA60088D500 /* UTF8.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C4780E16F5CD00B34460 /* Vector.h in Headers */ = {isa = PBXBuildFile; fileRef = 6592C316098B7DE10003D4F6 /* Vector.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C4790E16F5CD00B34460 /* VectorTraits.h in Headers */ = {isa = PBXBuildFile; fileRef = 6592C317098B7DE10003D4F6 /* VectorTraits.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 */; };
BC18C5260E16FCA700B34460 /* StringPrototype.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = BC18C5250E16FCA700B34460 /* StringPrototype.lut.h */; };
@@ -744,10 +610,6 @@
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 */; };
BC3C4CA01458F5450025FB62 /* JSGlobalThis.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC3C4C9F1458F5450025FB62 /* JSGlobalThis.cpp */; };
- BC5F7BBE11823B590052C02C /* Atomics.h in Headers */ = {isa = PBXBuildFile; fileRef = BC5F7BBB11823B590052C02C /* Atomics.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC5F7BBF11823B590052C02C /* ThreadingPrimitives.h in Headers */ = {isa = PBXBuildFile; fileRef = BC5F7BBC11823B590052C02C /* ThreadingPrimitives.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC5F7BC011823B590052C02C /* ThreadSafeRefCounted.h in Headers */ = {isa = PBXBuildFile; fileRef = BC5F7BBD11823B590052C02C /* ThreadSafeRefCounted.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC66BAE413F492CC00C23FAE /* Compiler.h in Headers */ = {isa = PBXBuildFile; fileRef = BC66BAE213F4928F00C23FAE /* Compiler.h */; settings = {ATTRIBUTES = (Private, ); }; };
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 */; };
@@ -766,63 +628,40 @@
BCDE3AB80E6C82F5001453A7 /* Structure.h in Headers */ = {isa = PBXBuildFile; fileRef = BCDE3AB10E6C82CF001453A7 /* Structure.h */; settings = {ATTRIBUTES = (Private, ); }; };
BCDE3B430E6C832D001453A7 /* Structure.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCDE3AB00E6C82CF001453A7 /* Structure.cpp */; };
BCF605140E203EF800B9A64D /* ArgList.h in Headers */ = {isa = PBXBuildFile; fileRef = BCF605120E203EF800B9A64D /* ArgList.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BCFBE696122560E800309E9D /* PassOwnArrayPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = BCFBE695122560E800309E9D /* PassOwnArrayPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
BCFD8C920EEB2EE700283848 /* JumpTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCFD8C900EEB2EE700283848 /* JumpTable.cpp */; };
BCFD8C930EEB2EE700283848 /* JumpTable.h in Headers */ = {isa = PBXBuildFile; fileRef = BCFD8C910EEB2EE700283848 /* JumpTable.h */; };
- C0A272630E50A06300E96E15 /* NotFound.h in Headers */ = {isa = PBXBuildFile; fileRef = C0A2723F0E509F1E00E96E15 /* NotFound.h */; settings = {ATTRIBUTES = (Private, ); }; };
C22B31B9140577D700DB475A /* SamplingCounter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F77008E1402FDD60078EB39 /* SamplingCounter.h */; settings = {ATTRIBUTES = (Private, ); }; };
C22C52F113FAF6EF00B7DC0D /* bignum-dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = C22C529013FAF6EF00B7DC0D /* bignum-dtoa.cc */; };
- C22C52F213FAF6EF00B7DC0D /* bignum-dtoa.h in Headers */ = {isa = PBXBuildFile; fileRef = C22C529113FAF6EF00B7DC0D /* bignum-dtoa.h */; settings = {ATTRIBUTES = (Private, ); }; };
C22C52F313FAF6EF00B7DC0D /* bignum.cc in Sources */ = {isa = PBXBuildFile; fileRef = C22C529213FAF6EF00B7DC0D /* bignum.cc */; };
- C22C52F413FAF6EF00B7DC0D /* bignum.h in Headers */ = {isa = PBXBuildFile; fileRef = C22C529313FAF6EF00B7DC0D /* bignum.h */; settings = {ATTRIBUTES = (Private, ); }; };
C22C52F513FAF6EF00B7DC0D /* cached-powers.cc in Sources */ = {isa = PBXBuildFile; fileRef = C22C529413FAF6EF00B7DC0D /* cached-powers.cc */; };
- C22C52F613FAF6EF00B7DC0D /* cached-powers.h in Headers */ = {isa = PBXBuildFile; fileRef = C22C529513FAF6EF00B7DC0D /* cached-powers.h */; settings = {ATTRIBUTES = (Private, ); }; };
C22C52F713FAF6EF00B7DC0D /* diy-fp.cc in Sources */ = {isa = PBXBuildFile; fileRef = C22C529713FAF6EF00B7DC0D /* diy-fp.cc */; };
- C22C52F813FAF6EF00B7DC0D /* diy-fp.h in Headers */ = {isa = PBXBuildFile; fileRef = C22C529813FAF6EF00B7DC0D /* diy-fp.h */; settings = {ATTRIBUTES = (Private, ); }; };
C22C52F913FAF6EF00B7DC0D /* double-conversion.cc in Sources */ = {isa = PBXBuildFile; fileRef = C22C529913FAF6EF00B7DC0D /* double-conversion.cc */; };
- C22C52FA13FAF6EF00B7DC0D /* double-conversion.h in Headers */ = {isa = PBXBuildFile; fileRef = C22C529A13FAF6EF00B7DC0D /* double-conversion.h */; settings = {ATTRIBUTES = (Private, ); }; };
- C22C52FB13FAF6EF00B7DC0D /* double.h in Headers */ = {isa = PBXBuildFile; fileRef = C22C529B13FAF6EF00B7DC0D /* double.h */; settings = {ATTRIBUTES = (Private, ); }; };
C22C52FC13FAF6EF00B7DC0D /* fast-dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = C22C529C13FAF6EF00B7DC0D /* fast-dtoa.cc */; };
- C22C52FD13FAF6EF00B7DC0D /* fast-dtoa.h in Headers */ = {isa = PBXBuildFile; fileRef = C22C529D13FAF6EF00B7DC0D /* fast-dtoa.h */; settings = {ATTRIBUTES = (Private, ); }; };
C22C52FE13FAF6EF00B7DC0D /* fixed-dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = C22C529E13FAF6EF00B7DC0D /* fixed-dtoa.cc */; };
- C22C52FF13FAF6EF00B7DC0D /* fixed-dtoa.h in Headers */ = {isa = PBXBuildFile; fileRef = C22C529F13FAF6EF00B7DC0D /* fixed-dtoa.h */; settings = {ATTRIBUTES = (Private, ); }; };
C22C531313FAF6EF00B7DC0D /* strtod.cc in Sources */ = {isa = PBXBuildFile; fileRef = C22C52B913FAF6EF00B7DC0D /* strtod.cc */; };
- C22C531413FAF6EF00B7DC0D /* strtod.h in Headers */ = {isa = PBXBuildFile; fileRef = C22C52BA13FAF6EF00B7DC0D /* strtod.h */; settings = {ATTRIBUTES = (Private, ); }; };
- C22C531513FAF6EF00B7DC0D /* utils.h in Headers */ = {isa = PBXBuildFile; fileRef = C22C52BB13FAF6EF00B7DC0D /* utils.h */; settings = {ATTRIBUTES = (Private, ); }; };
C240305514B404E60079EB64 /* CopiedSpace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C240305314B404C90079EB64 /* CopiedSpace.cpp */; };
C2B916C214DA014E00CBAC86 /* MarkedAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = C2B916C114DA014E00CBAC86 /* MarkedAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
C2B916C514DA040C00CBAC86 /* MarkedAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2B916C414DA040C00CBAC86 /* MarkedAllocator.cpp */; };
C2C8D02D14A3C6E000578E65 /* CopiedSpaceInlineMethods.h in Headers */ = {isa = PBXBuildFile; fileRef = C2C8D02B14A3C6B200578E65 /* CopiedSpaceInlineMethods.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, ); }; };
- C2D9CA1314BCC04600304B46 /* CheckedBoolean.h in Headers */ = {isa = PBXBuildFile; fileRef = C2D9CA1214BCC04600304B46 /* CheckedBoolean.h */; settings = {ATTRIBUTES = (Private, ); }; };
C2EAA3FA149A835E00FCE112 /* CopiedSpace.h in Headers */ = {isa = PBXBuildFile; fileRef = C2EAA3F8149A830800FCE112 /* CopiedSpace.h */; settings = {ATTRIBUTES = (Private, ); }; };
C2EAD2FC14F0249800A4B159 /* CopiedAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = C2EAD2FB14F0249800A4B159 /* CopiedAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
- C2EE59A013FC973F009CEAFE /* DecimalNumber.h in Headers */ = {isa = PBXBuildFile; fileRef = C2EE599E13FC972A009CEAFE /* DecimalNumber.h */; settings = {ATTRIBUTES = (Private, ); }; };
C2EE59A113FC9768009CEAFE /* DecimalNumber.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2EE599D13FC972A009CEAFE /* DecimalNumber.cpp */; };
- D7A46A4F1338FFEA00ED695C /* DynamicAnnotations.h in Headers */ = {isa = PBXBuildFile; fileRef = D75AF59612F8CB9500FC0ADF /* DynamicAnnotations.h */; settings = {ATTRIBUTES = (Private, ); }; };
- DD377CBC12072C18006A2517 /* Bitmap.h in Headers */ = {isa = PBXBuildFile; fileRef = DD377CBB12072C18006A2517 /* Bitmap.h */; settings = {ATTRIBUTES = (Private, ); }; };
DDF7ABD411F60ED200108E36 /* GCActivityCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = DDF7ABD211F60ED200108E36 /* GCActivityCallback.h */; settings = {ATTRIBUTES = (Private, ); }; };
DDF7ABD511F60ED200108E36 /* GCActivityCallbackCF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDF7ABD311F60ED200108E36 /* GCActivityCallbackCF.cpp */; };
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 */; };
- E17FF771112131D200076A19 /* ValueCheck.h in Headers */ = {isa = PBXBuildFile; fileRef = E17FF770112131D200076A19 /* ValueCheck.h */; settings = {ATTRIBUTES = (Private, ); }; };
E18E3A590DF9278C00D90B34 /* JSGlobalData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E18E3A570DF9278C00D90B34 /* JSGlobalData.cpp */; };
E1A862A90D7EBB76001EC6AA /* CollatorICU.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1A862A80D7EBB76001EC6AA /* CollatorICU.cpp */; settings = {COMPILER_FLAGS = "-fno-strict-aliasing"; }; };
E1A862D60D7F2B5C001EC6AA /* CollatorDefault.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1A862D50D7F2B5C001EC6AA /* CollatorDefault.cpp */; };
E1EE793D0D6C9B9200FEA3BA /* ThreadingPthreads.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1EE793C0D6C9B9200FEA3BA /* ThreadingPthreads.cpp */; };
E1EF79AA0CE97BA60088D500 /* UTF8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1EF79A80CE97BA60088D500 /* UTF8.cpp */; };
- E48E0F2D0F82151700A8CA37 /* FastAllocBase.h in Headers */ = {isa = PBXBuildFile; fileRef = E48E0F2C0F82151700A8CA37 /* FastAllocBase.h */; settings = {ATTRIBUTES = (Private, ); }; };
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, ); }; };
- E4D8CEFB12FC439600BC9F5A /* BloomFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D8CE9B12FC42E100BC9F5A /* BloomFilter.h */; settings = {ATTRIBUTES = (Private, ); }; };
- F3BD31ED126735770065467F /* TextPosition.h in Headers */ = {isa = PBXBuildFile; fileRef = F3BD31D0126730180065467F /* TextPosition.h */; settings = {ATTRIBUTES = (Private, ); }; };
F69E86C314C6E551002C2C62 /* NumberOfCores.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F69E86C114C6E551002C2C62 /* NumberOfCores.cpp */; };
- F69E86C414C6E551002C2C62 /* NumberOfCores.h in Headers */ = {isa = PBXBuildFile; fileRef = F69E86C214C6E551002C2C62 /* NumberOfCores.h */; };
- FDA15C1E12B0305C003A583A /* Complex.h in Headers */ = {isa = PBXBuildFile; fileRef = FDA15C1612B03028003A583A /* Complex.h */; settings = {ATTRIBUTES = (Private, ); }; };
- FE1B447A0ECCD73B004F4DD1 /* StdLibExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1B44790ECCD73B004F4DD1 /* StdLibExtras.h */; settings = {ATTRIBUTES = (Private, ); }; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -920,11 +759,14 @@
0896C29E1265AB0900B1CDD3 /* StringConcatenate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StringConcatenate.h; path = text/StringConcatenate.h; sourceTree = "<group>"; };
08DDA5BB12645F1D00751732 /* UStringBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UStringBuilder.h; sourceTree = "<group>"; };
08E279E80EF83B10007DB523 /* RandomNumberSeed.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RandomNumberSeed.h; sourceTree = "<group>"; };
+ 0A4337BA1506218800991C95 /* DFGRedundantPhiEliminationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGRedundantPhiEliminationPhase.cpp; path = dfg/DFGRedundantPhiEliminationPhase.cpp; sourceTree = "<group>"; };
+ 0A4337BD1506219B00991C95 /* DFGRedundantPhiEliminationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGRedundantPhiEliminationPhase.h; path = dfg/DFGRedundantPhiEliminationPhase.h; sourceTree = "<group>"; };
0B330C260F38C62300692DE3 /* TypeTraits.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TypeTraits.cpp; sourceTree = "<group>"; };
0B4D7E620F319AC800AD7E58 /* TypeTraits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypeTraits.h; sourceTree = "<group>"; };
0BAC949E1338728400CF135B /* ThreadRestrictionVerifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadRestrictionVerifier.h; sourceTree = "<group>"; };
0BCD83541485841200EA2003 /* TemporaryChange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemporaryChange.h; sourceTree = "<group>"; };
0BF28A2811A33DC300638F84 /* SizeLimits.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SizeLimits.cpp; sourceTree = "<group>"; };
+ 0F0776BD14FF002800102332 /* JITCompilationEffort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITCompilationEffort.h; sourceTree = "<group>"; };
0F0B839514BCF45A00885B4F /* LLIntEntrypoints.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntEntrypoints.cpp; path = llint/LLIntEntrypoints.cpp; sourceTree = "<group>"; };
0F0B839614BCF45A00885B4F /* LLIntEntrypoints.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntEntrypoints.h; path = llint/LLIntEntrypoints.h; sourceTree = "<group>"; };
0F0B839714BCF45A00885B4F /* LLIntThunks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntThunks.cpp; path = llint/LLIntThunks.cpp; sourceTree = "<group>"; };
@@ -942,6 +784,7 @@
0F0FC45814BD15F100B81154 /* LLIntCallLinkInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLIntCallLinkInfo.h; sourceTree = "<group>"; };
0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommonSlowPaths.h; sourceTree = "<group>"; };
0F16D724142C39A200CF784A /* BitVector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BitVector.cpp; sourceTree = "<group>"; };
+ 0F1D085F150C5A800074D109 /* DFGNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGNode.cpp; path = dfg/DFGNode.cpp; sourceTree = "<group>"; };
0F21C26614BE5F5E00ADC64B /* JITDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITDriver.h; sourceTree = "<group>"; };
0F21C27914BE727300ADC64B /* CodeSpecializationKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeSpecializationKind.h; sourceTree = "<group>"; };
0F21C27A14BE727300ADC64B /* ExecutionHarness.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExecutionHarness.h; sourceTree = "<group>"; };
@@ -971,6 +814,9 @@
0F4680D114BBC5F800BFE272 /* HostCallReturnValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HostCallReturnValue.h; sourceTree = "<group>"; };
0F55F0F114D1063600AC7649 /* AbstractPC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AbstractPC.cpp; sourceTree = "<group>"; };
0F55F0F214D1063600AC7649 /* AbstractPC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AbstractPC.h; sourceTree = "<group>"; };
+ 0F56A1D115000F31002992B1 /* ExecutionCounter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExecutionCounter.h; sourceTree = "<group>"; };
+ 0F56A1D415001CF2002992B1 /* ExecutionCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExecutionCounter.cpp; sourceTree = "<group>"; };
+ 0F56A1D6150028B9002992B1 /* SimpleStats.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimpleStats.h; sourceTree = "<group>"; };
0F5F08CC146BE602000472A9 /* DFGByteCodeCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGByteCodeCache.h; path = dfg/DFGByteCodeCache.h; sourceTree = "<group>"; };
0F5F08CE146C762F000472A9 /* UnconditionalFinalizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnconditionalFinalizer.h; sourceTree = "<group>"; };
0F62016D143FCD2F0068B77C /* DFGAbstractState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGAbstractState.cpp; path = dfg/DFGAbstractState.cpp; sourceTree = "<group>"; };
@@ -1008,6 +854,7 @@
0FB5467814F5C468002C2989 /* LazyOperandValueProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LazyOperandValueProfile.cpp; sourceTree = "<group>"; };
0FB5467A14F5C7D4002C2989 /* MethodOfGettingAValueProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MethodOfGettingAValueProfile.h; sourceTree = "<group>"; };
0FB5467C14F5CFD3002C2989 /* MethodOfGettingAValueProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MethodOfGettingAValueProfile.cpp; sourceTree = "<group>"; };
+ 0FB5468E14FADA6F002C2989 /* RefCountedArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RefCountedArray.h; 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>"; };
@@ -1216,8 +1063,8 @@
5D6A566A0F05995500266145 /* Threading.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Threading.cpp; sourceTree = "<group>"; };
5DA479650CFBCF56009328A0 /* TCPackedCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TCPackedCache.h; sourceTree = "<group>"; };
5DAFD6CB146B686300FBEFB4 /* JSC.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = JSC.xcconfig; sourceTree = "<group>"; };
- 5DAFD6CC146B68B900FBEFB4 /* TestRegExp.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = TestRegExp.xcconfig; sourceTree = "<group>"; };
5DBD18AF0C5401A700C15EAE /* MallocZoneSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MallocZoneSupport.h; 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>"; };
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>"; };
@@ -1526,7 +1373,7 @@
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>"; };
BC021BF1136900C300FC5467 /* CompilerVersion.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = CompilerVersion.xcconfig; sourceTree = "<group>"; };
- BC021BF2136900C300FC5467 /* TestAPI.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = TestAPI.xcconfig; sourceTree = "<group>"; };
+ BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = ToolExecutable.xcconfig; sourceTree = "<group>"; };
BC02E9040E1839DB000F9297 /* ErrorConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ErrorConstructor.cpp; sourceTree = "<group>"; };
BC02E9050E1839DB000F9297 /* ErrorConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ErrorConstructor.h; sourceTree = "<group>"; };
BC02E9060E1839DB000F9297 /* ErrorPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ErrorPrototype.cpp; sourceTree = "<group>"; };
@@ -1867,6 +1714,7 @@
0F46809C14BA7F4D00BFE272 /* llint */ = {
isa = PBXGroup;
children = (
+ 5DDDF44614FEE72200B4FB4D /* LLIntDesiredOffsets.h */,
0F0B839514BCF45A00885B4F /* LLIntEntrypoints.cpp */,
0F0B839614BCF45A00885B4F /* LLIntEntrypoints.h */,
0F0B839714BCF45A00885B4F /* LLIntThunks.cpp */,
@@ -1920,6 +1768,7 @@
1429D92C0ED22D7000B89619 /* jit */ = {
isa = PBXGroup;
children = (
+ 0F0776BD14FF002800102332 /* JITCompilationEffort.h */,
0F4680D014BBC5F800BFE272 /* HostCallReturnValue.cpp */,
0F4680D114BBC5F800BFE272 /* HostCallReturnValue.h */,
0F46807F14BA572700BFE272 /* JITExceptions.cpp */,
@@ -2104,8 +1953,7 @@
449097EE0F8F81B50076A327 /* FeatureDefines.xcconfig */,
5DAFD6CB146B686300FBEFB4 /* JSC.xcconfig */,
1C9051430BA9E8A70081E9D0 /* JavaScriptCore.xcconfig */,
- BC021BF2136900C300FC5467 /* TestAPI.xcconfig */,
- 5DAFD6CC146B68B900FBEFB4 /* TestRegExp.xcconfig */,
+ BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */,
1C9051420BA9E8A70081E9D0 /* Version.xcconfig */,
);
path = Configurations;
@@ -2204,6 +2052,7 @@
A7A1F7AB0F252B3C00E184E2 /* ByteArray.h */,
A7BC0C81140608B000B1BB71 /* CheckedArithmetic.h */,
C2D9CA1214BCC04600304B46 /* CheckedBoolean.h */,
+ 0FB5468E14FADA6F002C2989 /* RefCountedArray.h */,
BC66BAE213F4928F00C23FAE /* Compiler.h */,
FDA15C1612B03028003A583A /* Complex.h */,
97941A7C1302A098004A3447 /* CryptographicallyRandomNumber.cpp */,
@@ -2308,6 +2157,7 @@
A7C40C08130B057D00D002A1 /* SentinelLinkedList.h */,
76FB9F1012E851960051A2EB /* SHA1.cpp */,
76FB9F0E12E851860051A2EB /* SHA1.h */,
+ 0F56A1D6150028B9002992B1 /* SimpleStats.h */,
A7C40C09130B057D00D002A1 /* SinglyLinkedList.h */,
0BF28A2811A33DC300638F84 /* SizeLimits.cpp */,
0F2E5BF5146357D2003EB2EB /* Spectrum.h */,
@@ -2656,6 +2506,7 @@
86EC9DB31328DF44002B2AD7 /* dfg */ = {
isa = PBXGroup;
children = (
+ 0F1D085F150C5A800074D109 /* DFGNode.cpp */,
0FFFC94914EF909500C72532 /* DFGArithNodeFlagsInferencePhase.cpp */,
0FFFC94A14EF909500C72532 /* DFGArithNodeFlagsInferencePhase.h */,
0F62016D143FCD2F0068B77C /* DFGAbstractState.cpp */,
@@ -2704,6 +2555,8 @@
0FFFC95014EF909500C72532 /* DFGPhase.h */,
0FFFC95114EF909500C72532 /* DFGPredictionPropagationPhase.cpp */,
0FFFC95214EF909500C72532 /* DFGPredictionPropagationPhase.h */,
+ 0A4337BA1506218800991C95 /* DFGRedundantPhiEliminationPhase.cpp */,
+ 0A4337BD1506219B00991C95 /* DFGRedundantPhiEliminationPhase.h */,
86EC9DC11328DF82002B2AD7 /* DFGRegisterBank.h */,
86BB09BE138E381B0056702F /* DFGRepatch.cpp */,
86BB09BF138E381B0056702F /* DFGRepatch.h */,
@@ -2782,6 +2635,8 @@
969A078F0ED1D3AE00F1F681 /* bytecode */ = {
isa = PBXGroup;
children = (
+ 0F56A1D415001CF2002992B1 /* ExecutionCounter.cpp */,
+ 0F56A1D115000F31002992B1 /* ExecutionCounter.h */,
0FB5467C14F5CFD3002C2989 /* MethodOfGettingAValueProfile.cpp */,
0FB5467A14F5C7D4002C2989 /* MethodOfGettingAValueProfile.h */,
0FB5467814F5C468002C2989 /* LazyOperandValueProfile.cpp */,
@@ -2910,89 +2765,54 @@
buildActionMask = 2147483647;
files = (
860161E30F3A83C100F84710 /* AbstractMacroAssembler.h in Headers */,
- A1D764521354448B00C5C7C0 /* Alignment.h in Headers */,
- BC18C3E40E16F5CD00B34460 /* AlwaysInline.h in Headers */,
BC18C3E50E16F5CD00B34460 /* APICast.h in Headers */,
865F408810E7D56300947361 /* APIShims.h in Headers */,
BCF605140E203EF800B9A64D /* ArgList.h in Headers */,
BC257DE80E1F51C50016B6C9 /* Arguments.h in Headers */,
86D3B2C410156BDE002865E7 /* ARMAssembler.h in Headers */,
86ADD1450FDDEA980006EEC2 /* ARMv7Assembler.h in Headers */,
- A73BE169148420520091204B /* ArrayBuffer.h in Headers */,
- C2D9CA1314BCC04600304B46 /* CheckedBoolean.h in Headers */,
- A73BE16B148420520091204B /* ArrayBufferView.h in Headers */,
C2EAD2FC14F0249800A4B159 /* CopiedAllocator.h in Headers */,
C2B916C214DA014E00CBAC86 /* MarkedAllocator.h in Headers */,
BC18C3E60E16F5CD00B34460 /* ArrayConstructor.h in Headers */,
BC18C3E70E16F5CD00B34460 /* ArrayPrototype.h in Headers */,
BC18C5240E16FC8A00B34460 /* ArrayPrototype.lut.h in Headers */,
- BC18C3E90E16F5CD00B34460 /* ASCIICType.h in Headers */,
- 434A8E7114956A50009126F7 /* ASCIIFastPath.h in Headers */,
9688CB150ED12B4E001D649F /* AssemblerBuffer.h in Headers */,
86D3B2C510156BDE002865E7 /* AssemblerBufferWithConstantPool.h in Headers */,
- BC18C3EA0E16F5CD00B34460 /* Assertions.h in Headers */,
A784A26111D16622005776AC /* ASTBuilder.h in Headers */,
- BC5F7BBE11823B590052C02C /* Atomics.h in Headers */,
- 868BFA09117CEFD100B908B1 /* AtomicString.h in Headers */,
- 86F38859121130CA007A7CE3 /* AtomicStringHash.h in Headers */,
- 868BFA0A117CEFD100B908B1 /* AtomicStringImpl.h in Headers */,
- BC18C3EB0E16F5CD00B34460 /* AVLTree.h in Headers */,
147B83AC0E6DB8C9004775A4 /* BatchedTransitionOptimizer.h in Headers */,
866739D213BFDE710023D87C /* BigInteger.h in Headers */,
- C22C52F213FAF6EF00B7DC0D /* bignum-dtoa.h in Headers */,
- C22C52F413FAF6EF00B7DC0D /* bignum.h in Headers */,
1A08277A142168D70090CCAC /* BinarySemaphore.h in Headers */,
- DD377CBC12072C18006A2517 /* Bitmap.h in Headers */,
- 0FD82F4B142806A100179C94 /* BitVector.h in Headers */,
- A7C40C0A130B057D00D002A1 /* BlockStack.h in Headers */,
- E4D8CEFB12FC439600BC9F5A /* BloomFilter.h in Headers */,
BC18C3EC0E16F5CD00B34460 /* BooleanObject.h in Headers */,
- 0FD82E85141F3FE300179C94 /* BoundsCheckedPointer.h in Headers */,
C2C8D03014A3CEFC00578E65 /* CopiedBlock.h in Headers */,
- 86676D5211FED9BC004B6863 /* BumpPointerAllocator.h in Headers */,
C2EAA3FA149A835E00FCE112 /* CopiedSpace.h in Headers */,
C2C8D02D14A3C6E000578E65 /* CopiedSpaceInlineMethods.h in Headers */,
- A7A1F7AD0F252B3C00E184E2 /* ByteArray.h in Headers */,
969A07230ED1CE3300F1F681 /* BytecodeGenerator.h in Headers */,
- C22C52F613FAF6EF00B7DC0D /* cached-powers.h in Headers */,
869D04AF1193B54D00803475 /* CachedTranscendentalFunction.h in Headers */,
BC18C3ED0E16F5CD00B34460 /* CallData.h in Headers */,
1429D8DE0ED2205B00B89619 /* CallFrame.h in Headers */,
95E3BC050E1AE68200B2D1C1 /* CallIdentifier.h in Headers */,
A7521E131429169A003C8D0C /* CardSet.h in Headers */,
- 2CFC5D1E12F45B48004914E2 /* CharacterNames.h in Headers */,
- A7BC0C82140608B000B1BB71 /* CheckedArithmetic.h in Headers */,
BC6AAAE50E1F426500AD87D8 /* ClassInfo.h in Headers */,
969A07970ED1D3AE00F1F681 /* CodeBlock.h in Headers */,
86E116B10FE75AC800B512BC /* CodeLocation.h in Headers */,
0FBD7E691447999600481315 /* CodeOrigin.h in Headers */,
- BC18C3F00E16F5CD00B34460 /* Collator.h in Headers */,
BC18C3F30E16F5CD00B34460 /* CommonIdentifiers.h in Headers */,
0FD82E39141AB14D00179C94 /* CompactJITCodeMap.h in Headers */,
- BC66BAE413F492CC00C23FAE /* Compiler.h in Headers */,
BC18C3F40E16F5CD00B34460 /* Completion.h in Headers */,
- FDA15C1E12B0305C003A583A /* Complex.h in Headers */,
BC18C3F50E16F5CD00B34460 /* config.h in Headers */,
144836E7132DA7BE005BE785 /* ConservativeRoots.h in Headers */,
BC18C3F60E16F5CD00B34460 /* ConstructData.h in Headers */,
5DE6E5B30E1728EC00180407 /* create_hash_table in Headers */,
- 97941A7F1302A098004A3447 /* CryptographicallyRandomNumber.h in Headers */,
- 86565743115BE3DA00291F40 /* CString.h in Headers */,
- 180B9B080F16D94F009BDBC5 /* CurrentTime.h in Headers */,
0F426A4B1460CD6E00131F8F /* DataFormat.h in Headers */,
BCD2034A0E17135E002C7E82 /* DateConstructor.h in Headers */,
41359CF30FDD89AD00206180 /* DateConversion.h in Headers */,
BC1166020E1997B4008066DD /* DateInstance.h in Headers */,
14A1563210966365006FA260 /* DateInstanceCache.h in Headers */,
- 41359CF70FDD89CB00206180 /* DateMath.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 */,
- C2EE59A013FC973F009CEAFE /* DecimalNumber.h in Headers */,
- 5135FAF212D26ACE003C083B /* Decoder.h in Headers */,
- BC18C3FC0E16F5CD00B34460 /* Deque.h in Headers */,
0F620178143FCD440068B77C /* DFGAbstractState.h in Headers */,
0F620177143FCD3F0068B77C /* DFGAbstractValue.h in Headers */,
0FC0976D1468AB4E00CF2442 /* DFGAssemblyHelpers.h in Headers */,
@@ -3019,14 +2839,6 @@
86EC9DD31328DF82002B2AD7 /* DFGSpeculativeJIT.h in Headers */,
0FC097A2146B28CC00CF2442 /* DFGThunks.h in Headers */,
0F620174143FCD330068B77C /* DFGVariableAccessData.h in Headers */,
- BC18C3FD0E16F5CD00B34460 /* DisallowCType.h in Headers */,
- C22C52F813FAF6EF00B7DC0D /* diy-fp.h in Headers */,
- C22C52FA13FAF6EF00B7DC0D /* double-conversion.h in Headers */,
- C22C52FB13FAF6EF00B7DC0D /* double.h in Headers */,
- 14456A321314657800212CA3 /* DoublyLinkedList.h in Headers */,
- BC18C3FE0E16F5CD00B34460 /* dtoa.h in Headers */,
- D7A46A4F1338FFEA00ED695C /* DynamicAnnotations.h in Headers */,
- 5135FAF312D26AD1003C083B /* Encoder.h in Headers */,
BC3046070E1F497F003232CF /* Error.h in Headers */,
BC02E90D0E1839DB000F9297 /* ErrorConstructor.h in Headers */,
BC02E98D0E183E38000F9297 /* ErrorInstance.h in Headers */,
@@ -3035,42 +2847,19 @@
BC18C4000E16F5CD00B34460 /* ExceptionHelpers.h in Headers */,
86CAFEE31035DDE60028A609 /* Executable.h in Headers */,
A766B44F0EE8DCD1009518CA /* ExecutableAllocator.h in Headers */,
- A7FEE67614837B32005DC1A6 /* ExportMacros.h in Headers */,
- C22C52FD13FAF6EF00B7DC0D /* fast-dtoa.h in Headers */,
- E48E0F2D0F82151700A8CA37 /* FastAllocBase.h in Headers */,
- BC18C4020E16F5CD00B34460 /* FastMalloc.h in Headers */,
- C22C52FF13FAF6EF00B7DC0D /* fixed-dtoa.h in Headers */,
- A7F19ECE11DD490900931E70 /* FixedArray.h in Headers */,
- A73BE16D148420520091204B /* Float32Array.h in Headers */,
- A73BE16F148420520091204B /* Float64Array.h in Headers */,
- BC18C4030E16F5CD00B34460 /* Forward.h in Headers */,
- 1AA9E5511498093500001A8A /* Functional.h in Headers */,
BC18C4040E16F5CD00B34460 /* FunctionConstructor.h in Headers */,
BC18C4050E16F5CD00B34460 /* FunctionPrototype.h in Headers */,
DDF7ABD411F60ED200108E36 /* GCActivityCallback.h in Headers */,
- BC18C4060E16F5CD00B34460 /* GetPtr.h in Headers */,
142E3134134FF0A600AFADB5 /* Handle.h in Headers */,
142E3136134FF0A600AFADB5 /* HandleHeap.h in Headers */,
142E3138134FF0A600AFADB5 /* HandleStack.h in Headers */,
1478297B1379E8A800A7C2A3 /* HandleTypes.h in Headers */,
- BC18C4080E16F5CD00B34460 /* HashCountedSet.h in Headers */,
- BC18C4090E16F5CD00B34460 /* HashFunctions.h in Headers */,
- BC18C40A0E16F5CD00B34460 /* HashIterators.h in Headers */,
- BC18C40B0E16F5CD00B34460 /* HashMap.h in Headers */,
- BC18C40C0E16F5CD00B34460 /* HashSet.h in Headers */,
- BC18C40D0E16F5CD00B34460 /* HashTable.h in Headers */,
- BC18C40E0E16F5CD00B34460 /* HashTraits.h in Headers */,
14BA7A9813AADFF8005B7C2C /* Heap.h in Headers */,
C2C8D03114A3CEFC00578E65 /* HeapBlock.h in Headers */,
14F97447138C853E00DA1C67 /* HeapRootVisitor.h in Headers */,
- 7186A6EC13100BA5004479E1 /* HexNumber.h in Headers */,
BC18C40F0E16F5CD00B34460 /* Identifier.h in Headers */,
BC18C4100E16F5CD00B34460 /* InitializeThreading.h in Headers */,
969A07990ED1D3AE00F1F681 /* Instruction.h in Headers */,
- A73BE173148420520091204B /* Int16Array.h in Headers */,
- A73BE175148420520091204B /* Int32Array.h in Headers */,
- A73BE171148420520091204B /* Int8Array.h in Headers */,
- A73BE180148420A80091204B /* IntegralTypedArrayBase.h in Headers */,
BC11667B0E199C05008066DD /* InternalFunction.h in Headers */,
1429D77C0ED20D7300B89619 /* Interpreter.h in Headers */,
860BD801148EA6F200112B2F /* Intrinsic.h in Headers */,
@@ -3135,12 +2924,9 @@
BC18C52E0E16FCE100B34460 /* Lexer.lut.h in Headers */,
86D3B3C310159D7F002865E7 /* LinkBuffer.h in Headers */,
0F431738146BAC69007E3890 /* ListableHandler.h in Headers */,
- BC18C4340E16F5CD00B34460 /* ListHashSet.h in Headers */,
- BC18C4350E16F5CD00B34460 /* ListRefPtr.h in Headers */,
A7E2EA6B0FB460CF00601F06 /* LiteralParser.h in Headers */,
142E3139134FF0A600AFADB5 /* Local.h in Headers */,
142E313A134FF0A600AFADB5 /* LocalScope.h in Headers */,
- BC18C4360E16F5CD00B34460 /* Locker.h in Headers */,
BC18C4370E16F5CD00B34460 /* Lookup.h in Headers */,
14B723B812D7DA6F003BD5ED /* MachineStackMarker.h in Headers */,
86C36EEA0EE1289D00B3DF59 /* MacroAssembler.h in Headers */,
@@ -3152,29 +2938,18 @@
860161E40F3A83C100F84710 /* MacroAssemblerX86.h in Headers */,
860161E50F3A83C100F84710 /* MacroAssemblerX86_64.h in Headers */,
860161E60F3A83C100F84710 /* MacroAssemblerX86Common.h in Headers */,
- BC18C4390E16F5CD00B34460 /* MainThread.h in Headers */,
- BC18C43A0E16F5CD00B34460 /* MallocZoneSupport.h in Headers */,
142D6F0913539A2800B02E86 /* MarkedBlock.h in Headers */,
141448CB13A176EC00F5BA1A /* MarkedBlockSet.h in Headers */,
14D2F3DB139F4BE200491031 /* MarkedSpace.h in Headers */,
142D6F1213539A4100B02E86 /* MarkStack.h in Headers */,
- BC18C43B0E16F5CD00B34460 /* MathExtras.h in Headers */,
BC18C43C0E16F5CD00B34460 /* MathObject.h in Headers */,
BC18C52A0E16FCC200B34460 /* MathObject.lut.h in Headers */,
- 511FC4CB117EE2A800425272 /* MD5.h in Headers */,
90213E3E123A40C200D422F3 /* MemoryStatistics.h in Headers */,
- BC18C43E0E16F5CD00B34460 /* MessageQueue.h in Headers */,
- 0F963B2D13F854020002D9B2 /* MetaAllocator.h in Headers */,
- 0F963B2F13FC66BB0002D9B2 /* MetaAllocatorHandle.h in Headers */,
86C568E211A213EE0007F7F0 /* MIPSAssembler.h in Headers */,
BC02E9110E1839DB000F9297 /* NativeErrorConstructor.h in Headers */,
BC02E9130E1839DB000F9297 /* NativeErrorPrototype.h in Headers */,
7EFF00640EC05A9A00AA7C93 /* NodeInfo.h in Headers */,
BC18C43F0E16F5CD00B34460 /* Nodes.h in Headers */,
- BC18C4400E16F5CD00B34460 /* Noncopyable.h in Headers */,
- 65E1A3DF122B894500B26097 /* NonCopyingSort.h in Headers */,
- C0A272630E50A06300E96E15 /* NotFound.h in Headers */,
- 933F5CDC1269229B0049191E /* NullPtr.h in Headers */,
BC18C4410E16F5CD00B34460 /* NumberConstructor.h in Headers */,
BC18C4420E16F5CD00B34460 /* NumberConstructor.lut.h in Headers */,
BC18C4430E16F5CD00B34460 /* NumberObject.h in Headers */,
@@ -3186,34 +2961,12 @@
969A079B0ED1D3AE00F1F681 /* Opcode.h in Headers */,
BC18C4480E16F5CD00B34460 /* Operations.h in Headers */,
0FE228ED1436AB2700196C48 /* Options.h in Headers */,
- 1400067712A6F7830064D123 /* OSAllocator.h in Headers */,
- 97941A5A13029ACC004A3447 /* OSRandomSource.h in Headers */,
- BC18C4490E16F5CD00B34460 /* OwnArrayPtr.h in Headers */,
- BC18C44A0E16F5CD00B34460 /* OwnPtr.h in Headers */,
- 4409D8470FAF80A200523B87 /* OwnPtrCommon.h in Headers */,
- 0F636DA0142D27D700B2E66A /* PackedIntVector.h in Headers */,
- 8627E5EC11F1281900A313B5 /* PageAllocation.h in Headers */,
- 14FFF98D12BFFF7500795BB8 /* PageAllocationAligned.h in Headers */,
- 14B3EF0512BC24DD00D29EFF /* PageBlock.h in Headers */,
- 8690231512092D5C00630AF9 /* PageReservation.h in Headers */,
- 7934BB7B1361979300CB99A1 /* ParallelJobs.h in Headers */,
- 7934BB7D1361979400CB99A1 /* ParallelJobsGeneric.h in Headers */,
- 7934BB7E1361979400CB99A1 /* ParallelJobsLibdispatch.h in Headers */,
- 7934BB7F1361979400CB99A1 /* ParallelJobsOpenMP.h in Headers */,
- 2684B2D414D4A9B20072C0B6 /* ParsedURL.h in Headers */,
BC18C44B0E16F5CD00B34460 /* Parser.h in Headers */,
93052C350FB792190048FDC3 /* ParserArena.h in Headers */,
65303D641447B9E100D3F904 /* ParserTokens.h in Headers */,
- BCFBE696122560E800309E9D /* PassOwnArrayPtr.h in Headers */,
- 44DD48530FAEA85000D6B4EB /* PassOwnPtr.h in Headers */,
- BC18C44C0E16F5CD00B34460 /* PassRefPtr.h in Headers */,
- 651DCA04136A6FEF00F74194 /* PassTraits.h in Headers */,
- BC18C44F0E16F5CD00B34460 /* Platform.h in Headers */,
- A7D649AA1015224E009B2E1B /* PossiblyNull.h in Headers */,
0FD82E54141DAEEE00179C94 /* PredictedType.h in Headers */,
0FD82E55141DAEEE00179C94 /* PredictionTracker.h in Headers */,
BC18C4500E16F5CD00B34460 /* Profile.h in Headers */,
- 95CD45770E1C4FDD0085358E /* ProfileGenerator.h in Headers */,
BC18C4510E16F5CD00B34460 /* ProfileNode.h in Headers */,
BC18C4520E16F5CD00B34460 /* Profiler.h in Headers */,
A7FB61001040C38B0017A286 /* PropertyDescriptor.h in Headers */,
@@ -3222,14 +2975,6 @@
BC18C4550E16F5CD00B34460 /* PropertySlot.h in Headers */,
BC18C4560E16F5CD00B34460 /* Protect.h in Headers */,
147B84630E6DE6B1004775A4 /* PutPropertySlot.h in Headers */,
- 088FA5BC0EF76D4300578E6F /* RandomNumber.h in Headers */,
- 08E279E90EF83B10007DB523 /* RandomNumberSeed.h in Headers */,
- 2684B2D614D4A9B20072C0B6 /* RawURLBuffer.h in Headers */,
- 0F963B2713F753BB0002D9B2 /* RedBlackTree.h in Headers */,
- BC18C4570E16F5CD00B34460 /* RefCounted.h in Headers */,
- 90D3469C0E285280009492EE /* RefCountedLeakCounter.h in Headers */,
- BC18C4580E16F5CD00B34460 /* RefPtr.h in Headers */,
- BC18C4590E16F5CD00B34460 /* RefPtrHashMap.h in Headers */,
BC18C45A0E16F5CD00B34460 /* RegExp.h in Headers */,
A1712B3F11C7B228007A5315 /* RegExpCache.h in Headers */,
BCD202C20E1706A7002C7E82 /* RegExpConstructor.h in Headers */,
@@ -3243,15 +2988,10 @@
969A072B0ED1CE6900F1F681 /* RegisterID.h in Headers */,
86D3B3C410159D7F002865E7 /* RepatchBuffer.h in Headers */,
869EBCB70E8C6D4A008722CC /* ResultType.h in Headers */,
- BC18C4600E16F5CD00B34460 /* RetainPtr.h in Headers */,
C22B31B9140577D700DB475A /* SamplingCounter.h in Headers */,
1429D8860ED21C3D00B89619 /* SamplingTool.h in Headers */,
BC18C4610E16F5CD00B34460 /* ScopeChain.h in Headers */,
- 969A072C0ED1CE6900F1F681 /* SegmentedVector.h in Headers */,
- A7C40C0B130B057D00D002A1 /* SentinelLinkedList.h in Headers */,
86AE64AA135E5E1C00963012 /* SH4Assembler.h in Headers */,
- 76FB9F0F12E851860051A2EB /* SHA1.h in Headers */,
- A7C40C0C130B057D00D002A1 /* SinglyLinkedList.h in Headers */,
14BA78F113AAB88F005B7C2C /* SlotVisitor.h in Headers */,
933040040E6A749400786E6A /* SmallStrings.h in Headers */,
BC18C4640E16F5CD00B34460 /* SourceCode.h in Headers */,
@@ -3259,80 +2999,32 @@
E49DC16C12EF294E00184A1F /* SourceProviderCache.h in Headers */,
E49DC16D12EF295300184A1F /* SourceProviderCacheItem.h in Headers */,
A7386554118697B400540279 /* SpecializedThunkJIT.h in Headers */,
- 0F2E5BF7146357D5003EB2EB /* Spectrum.h in Headers */,
- 86D87DDB12BCAF94008E73A1 /* StackBounds.h in Headers */,
- 868BFA60117D048200B908B1 /* StaticConstructors.h in Headers */,
- FE1B447A0ECCD73B004F4DD1 /* StdLibExtras.h in Headers */,
A781E359141970C700094D90 /* StorageBarrier.h in Headers */,
A730B6121250068F009D25B1 /* StrictEvalActivation.h in Headers */,
- 86B99AE3117E578100DF5A90 /* StringBuffer.h in Headers */,
- 081469491264378500DFF935 /* StringBuilder.h in Headers */,
- 08CABBA61265AB3900B206CE /* StringConcatenate.h in Headers */,
BC18C4660E16F5CD00B34460 /* StringConstructor.h in Headers */,
- BC18C4670E16F5CD00B34460 /* StringExtras.h in Headers */,
- 868BFA0D117CEFD100B908B1 /* StringHash.h in Headers */,
- 5D63E9AD10F2BD6E00FC8AE9 /* StringHasher.h in Headers */,
- 868BFA0F117CEFD100B908B1 /* StringImpl.h in Headers */,
BC18C4680E16F5CD00B34460 /* StringObject.h in Headers */,
- 71DA9D82134F3F3D00B767E7 /* StringOperators.h in Headers */,
BC18C46A0E16F5CD00B34460 /* StringPrototype.h in Headers */,
BC18C5260E16FCA700B34460 /* StringPrototype.lut.h in Headers */,
142E313B134FF0A600AFADB5 /* Strong.h in Headers */,
145722861437E140005FDE26 /* StrongInlines.h in Headers */,
- C22C531413FAF6EF00B7DC0D /* strtod.h in Headers */,
BCDE3AB80E6C82F5001453A7 /* Structure.h in Headers */,
7E4EE7090EBB7963005934AA /* StructureChain.h in Headers */,
BCCF0D080EF0AAB900413C8F /* StructureStubInfo.h in Headers */,
BC9041480EB9250900FE26FA /* StructureTransitionTable.h in Headers */,
BC18C46B0E16F5CD00B34460 /* SymbolTable.h in Headers */,
A784A26411D16622005776AC /* SyntaxChecker.h in Headers */,
- BC18C46C0E16F5CD00B34460 /* TCPackedCache.h in Headers */,
- BC18C46D0E16F5CD00B34460 /* TCPageMap.h in Headers */,
- BC18C46E0E16F5CD00B34460 /* TCSpinLock.h in Headers */,
- BC18C46F0E16F5CD00B34460 /* TCSystemAlloc.h in Headers */,
- 0BCD83571485845200EA2003 /* TemporaryChange.h in Headers */,
971EDEA61169E0D3005E4262 /* Terminator.h in Headers */,
- F3BD31ED126735770065467F /* TextPosition.h in Headers */,
- 18BAB55410DAE066000D945B /* ThreadIdentifierDataPthreads.h in Headers */,
- BC18C4700E16F5CD00B34460 /* Threading.h in Headers */,
- BC5F7BBF11823B590052C02C /* ThreadingPrimitives.h in Headers */,
- 0BAC94A01338728400CF135B /* ThreadRestrictionVerifier.h in Headers */,
- BC5F7BC011823B590052C02C /* ThreadSafeRefCounted.h in Headers */,
- BC18C4710E16F5CD00B34460 /* ThreadSpecific.h in Headers */,
A7386556118697B400540279 /* ThunkGenerators.h in Headers */,
14A42E400F4F60EE00599099 /* TimeoutChecker.h in Headers */,
141448CD13A1783700F5BA1A /* TinyBloomFilter.h in Headers */,
5D53726F0E1C54880021E549 /* Tracing.h in Headers */,
- A73BE17E148420840091204B /* TypedArrayBase.h in Headers */,
- 0B4D7E630F319AC800AD7E58 /* TypeTraits.h in Headers */,
- A73BE179148420520091204B /* Uint16Array.h in Headers */,
866739D313BFDE710023D87C /* Uint16WithFraction.h in Headers */,
- A73BE17B148420520091204B /* Uint32Array.h in Headers */,
- A73BE177148420520091204B /* Uint8Array.h in Headers */,
0F5F08CF146C7633000472A9 /* UnconditionalFinalizer.h in Headers */,
- BC18C4730E16F5CD00B34460 /* Unicode.h in Headers */,
- BC18C4740E16F5CD00B34460 /* UnicodeIcu.h in Headers */,
- 0FD52AAE143035A00026DC9F /* UnionFind.h in Headers */,
- BC18C4750E16F5CD00B34460 /* UnusedParam.h in Headers */,
- 2684B2D514D4A9B20072C0B6 /* URLString.h in Headers */,
- 2684B2D714D4A9B20072C0B6 /* URLBuffer.h in Headers */,
- 2684B2D914D4A9B20072C0B6 /* URLCharacterTypes.h in Headers */,
- 2684B2DA14D4A9B20072C0B6 /* URLComponent.h in Headers */,
- 2684B2DC14D4A9B20072C0B6 /* URLEscape.h in Headers */,
- 2684B2DD14D4A9B20072C0B6 /* URLParser.h in Headers */,
- 2684B2DE14D4A9B20072C0B6 /* URLQueryCanonicalizer.h in Headers */,
- 2684B2E014D4A9B20072C0B6 /* URLSegments.h in Headers */,
BC18C4760E16F5CD00B34460 /* UString.h in Headers */,
08DDA5C11264631700751732 /* UStringBuilder.h in Headers */,
- BC18C4770E16F5CD00B34460 /* UTF8.h in Headers */,
- C22C531513FAF6EF00B7DC0D /* utils.h in Headers */,
- E17FF771112131D200076A19 /* ValueCheck.h in Headers */,
0F963B3813FC6FE90002D9B2 /* ValueProfile.h in Headers */,
0F426A481460CBB300131F8F /* ValueRecovery.h in Headers */,
- BC18C4780E16F5CD00B34460 /* Vector.h in Headers */,
- BC18C4790E16F5CD00B34460 /* VectorTraits.h in Headers */,
0F426A491460CBB700131F8F /* VirtualRegister.h in Headers */,
- 96DD73790F9DA3100027FBCC /* VMTags.h in Headers */,
0FC815151405119B00CFA603 /* VTableSpectrum.h in Headers */,
142E313C134FF0A600AFADB5 /* Weak.h in Headers */,
14BFCE6910CDB1FC00364CCE /* WeakGCMap.h in Headers */,
@@ -3341,8 +3033,6 @@
BC18C47A0E16F5CD00B34460 /* WebKitAvailability.h in Headers */,
A7DCB97312E5193F00911940 /* WriteBarrier.h in Headers */,
0FC8150A14043BF500CFA603 /* WriteBarrierSupport.h in Headers */,
- 868BFA18117CF19900B908B1 /* WTFString.h in Headers */,
- 86D08D5411793613006E5ED0 /* WTFThreadData.h in Headers */,
9688CB160ED12B4E001D649F /* X86Assembler.h in Headers */,
451539B912DC994500EF7AC4 /* Yarr.h in Headers */,
86704B8512DBA33700A9FE7B /* YarrInterpreter.h in Headers */,
@@ -3371,6 +3061,7 @@
0F0B83B914BCF95F00885B4F /* CallReturnOffsetToBytecodeOffset.h in Headers */,
0F0FC45A14BD15F500B81154 /* LLIntCallLinkInfo.h in Headers */,
0F21C26814BE5F6800ADC64B /* JITDriver.h in Headers */,
+ 95CD45770E1C4FDD0085358E /* ProfileGenerator.h in Headers */,
0F21C27C14BE727600ADC64B /* ExecutionHarness.h in Headers */,
0F21C27D14BE727A00ADC64B /* CodeSpecializationKind.h in Headers */,
0F21C27F14BEAA8200ADC64B /* BytecodeConventions.h in Headers */,
@@ -3378,8 +3069,6 @@
0F7B294B14C3CD2F007C3DB1 /* DFGCapabilities.h in Headers */,
0F7B294C14C3CD43007C3DB1 /* DFGByteCodeCache.h in Headers */,
0F7B294D14C3CD4C007C3DB1 /* DFGCommon.h in Headers */,
- 91A3905614C0F47200F67901 /* Uint8ClampedArray.h in Headers */,
- F69E86C414C6E551002C2C62 /* NumberOfCores.h in Headers */,
0F93329E14CA7DC50085F3C6 /* CallLinkStatus.h in Headers */,
0F9332A014CA7DCD0085F3C6 /* GetByIdStatus.h in Headers */,
0F9332A214CA7DD30085F3C6 /* MethodCallLinkStatus.h in Headers */,
@@ -3388,7 +3077,6 @@
0F55F0F514D1063C00AC7649 /* AbstractPC.h in Headers */,
0F66E16B14DF3F1600B7B2E4 /* DFGNodeReferenceBlob.h in Headers */,
0F66E16C14DF3F1600B7B2E4 /* DFGNodeUse.h in Headers */,
- 0F9FC8D114E612DA00D52AE0 /* DataLog.h in Headers */,
0F9FC8C414E1B60000D52AE0 /* PolymorphicPutByIdList.h in Headers */,
0F9FC8C514E1B60400D52AE0 /* PutKind.h in Headers */,
BCBE2CAE14E985AA000593AD /* GCAssertions.h in Headers */,
@@ -3401,6 +3089,9 @@
1497209114EB831500FEB1B7 /* PassWeak.h in Headers */,
0FB5467714F59B5C002C2989 /* LazyOperandValueProfile.h in Headers */,
0FB5467B14F5C7E1002C2989 /* MethodOfGettingAValueProfile.h in Headers */,
+ 0F0776BF14FF002B00102332 /* JITCompilationEffort.h in Headers */,
+ 0F56A1D315000F35002992B1 /* ExecutionCounter.h in Headers */,
+ 0A4337BE1506219B00991C95 /* DFGRedundantPhiEliminationPhase.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -3483,6 +3174,7 @@
buildConfigurationList = 149C275D08902AFE008A9EFC /* Build configuration list for PBXNativeTarget "JavaScriptCore" */;
buildPhases = (
5D2F7CF90C6875BB00B5B72B /* Update Info.plist with version information */,
+ A8D7082715049EA2001063BC /* Copy WTF Headers */,
932F5B3F0822A1C700736975 /* Headers */,
932F5B910822A1C700736975 /* Sources */,
932F5BD20822A1C700736975 /* Frameworks */,
@@ -3711,6 +3403,20 @@
shellPath = /bin/sh;
shellScript = "if [ \"${TARGET_GCC_VERSION}\" = \"LLVM_COMPILER\" ]; then\n exit 0;\nfi\n\nif [ -f ../../Tools/Scripts/check-for-exit-time-destructors ]; then\n ../../Tools/Scripts/check-for-exit-time-destructors || exit $?\nfi";
};
+ A8D7082715049EA2001063BC /* Copy WTF Headers */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Copy WTF Headers";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "# WTF_PRIVATE_HEADERS_PATH will be replaced by PRIVATE_HEADERS_FOLDER_PATH\n# in the equivalent build-phase when WTF is its own project.\nWTF_PRIVATE_HEADERS_PATH=\"/usr/local/include\"\n\nif [[ \"${DEPLOYMENT_LOCATION}\" == \"NO\" ]]; then\nPRIVATE_HEADERS_PATH=\"${TARGET_BUILD_DIR%%/}${WTF_PRIVATE_HEADERS_PATH}\"\nelse\nPRIVATE_HEADERS_PATH=\"${DSTROOT%%/}${WTF_PRIVATE_HEADERS_PATH}\"\nfi;\n\nmkdir -p \"${PRIVATE_HEADERS_PATH}\"\nrsync -av --prune-empty-dirs --exclude \".svn\" --exclude \"usr\" --exclude \"DerivedSources\" --include \"*/\" --include \"*.h\" --exclude \"*\" \"${SRCROOT}/wtf\" \"${PRIVATE_HEADERS_PATH}\"\n";
+ };
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -4010,6 +3716,9 @@
0FFFC95F14EF90BB00C72532 /* DFGVirtualRegisterAllocationPhase.cpp in Sources */,
0FB5467914F5C46B002C2989 /* LazyOperandValueProfile.cpp in Sources */,
0FB5467D14F5CFD6002C2989 /* MethodOfGettingAValueProfile.cpp in Sources */,
+ 0F56A1D515001CF4002992B1 /* ExecutionCounter.cpp in Sources */,
+ 0A4337BB1506218800991C95 /* DFGRedundantPhiEliminationPhase.cpp in Sources */,
+ 0F1D0861150C5A860074D109 /* DFGNode.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -4097,37 +3806,29 @@
};
0FF922CB14F46B130041A24E /* Debug */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 5DAFD6CB146B686300FBEFB4 /* JSC.xcconfig */;
+ baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */;
buildSettings = {
- PRODUCT_NAME = JSCLLIntOffsetsExtractor;
- USER_HEADER_SEARCH_PATHS = ". icu $(HEADER_SEARCH_PATHS) $(BUILT_PRODUCTS_DIR)/LLIntOffsets";
};
name = Debug;
};
0FF922CC14F46B130041A24E /* Release */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 5DAFD6CB146B686300FBEFB4 /* JSC.xcconfig */;
+ baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */;
buildSettings = {
- PRODUCT_NAME = JSCLLIntOffsetsExtractor;
- USER_HEADER_SEARCH_PATHS = ". icu $(HEADER_SEARCH_PATHS) $(BUILT_PRODUCTS_DIR)/LLIntOffsets";
};
name = Release;
};
0FF922CD14F46B130041A24E /* Profiling */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 5DAFD6CB146B686300FBEFB4 /* JSC.xcconfig */;
+ baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */;
buildSettings = {
- PRODUCT_NAME = JSCLLIntOffsetsExtractor;
- USER_HEADER_SEARCH_PATHS = ". icu $(HEADER_SEARCH_PATHS) $(BUILT_PRODUCTS_DIR)/LLIntOffsets";
};
name = Profiling;
};
0FF922CE14F46B130041A24E /* Production */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 5DAFD6CB146B686300FBEFB4 /* JSC.xcconfig */;
+ baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */;
buildSettings = {
- PRODUCT_NAME = JSCLLIntOffsetsExtractor;
- USER_HEADER_SEARCH_PATHS = ". icu $(HEADER_SEARCH_PATHS) $(BUILT_PRODUCTS_DIR)/LLIntOffsets";
};
name = Production;
};
@@ -4249,49 +3950,49 @@
};
14BD59D70A3E8FC900BAF59C /* Debug */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = BC021BF2136900C300FC5467 /* TestAPI.xcconfig */;
+ baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */;
buildSettings = {
};
name = Debug;
};
14BD59D80A3E8FC900BAF59C /* Release */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = BC021BF2136900C300FC5467 /* TestAPI.xcconfig */;
+ baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */;
buildSettings = {
};
name = Release;
};
14BD59D90A3E8FC900BAF59C /* Production */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = BC021BF2136900C300FC5467 /* TestAPI.xcconfig */;
+ baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */;
buildSettings = {
};
name = Production;
};
6511230114046A4C002B101D /* Debug */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 5DAFD6CC146B68B900FBEFB4 /* TestRegExp.xcconfig */;
+ baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */;
buildSettings = {
};
name = Debug;
};
6511230214046A4C002B101D /* Release */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 5DAFD6CC146B68B900FBEFB4 /* TestRegExp.xcconfig */;
+ baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */;
buildSettings = {
};
name = Release;
};
6511230314046A4C002B101D /* Profiling */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 5DAFD6CC146B68B900FBEFB4 /* TestRegExp.xcconfig */;
+ baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */;
buildSettings = {
};
name = Profiling;
};
6511230414046A4C002B101D /* Production */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 5DAFD6CC146B68B900FBEFB4 /* TestRegExp.xcconfig */;
+ baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */;
buildSettings = {
};
name = Production;
@@ -4357,7 +4058,7 @@
};
A76148420E6402F700E357FA /* Profiling */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = BC021BF2136900C300FC5467 /* TestAPI.xcconfig */;
+ baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */;
buildSettings = {
};
name = Profiling;
diff --git a/Source/JavaScriptCore/KeywordLookupGenerator.py b/Source/JavaScriptCore/KeywordLookupGenerator.py
index dc779e0c5..29f50dfe0 100644
--- a/Source/JavaScriptCore/KeywordLookupGenerator.py
+++ b/Source/JavaScriptCore/KeywordLookupGenerator.py
@@ -169,7 +169,8 @@ class Trie:
def printAsC(self):
print("namespace JSC {")
print("")
- print("static ALWAYS_INLINE bool isIdentPart(int c);")
+ print("static ALWAYS_INLINE bool isIdentPart(LChar c);")
+ print("static ALWAYS_INLINE bool isIdentPart(UChar c);")
# 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("")
diff --git a/Source/JavaScriptCore/Target.pri b/Source/JavaScriptCore/Target.pri
index 8fa498c08..1480ae74b 100644
--- a/Source/JavaScriptCore/Target.pri
+++ b/Source/JavaScriptCore/Target.pri
@@ -53,6 +53,7 @@ SOURCES += \
bytecode/CallLinkStatus.cpp \
bytecode/CodeBlock.cpp \
bytecode/DFGExitProfile.cpp \
+ bytecode/ExecutionCounter.cpp \
bytecode/GetByIdStatus.cpp \
bytecode/JumpTable.cpp \
bytecode/LazyOperandValueProfile.cpp \
@@ -94,6 +95,7 @@ SOURCES += \
dfg/DFGDriver.cpp \
dfg/DFGGraph.cpp \
dfg/DFGJITCompiler.cpp \
+ dfg/DFGNode.cpp \
dfg/DFGOperations.cpp \
dfg/DFGOSREntry.cpp \
dfg/DFGOSRExit.cpp \
@@ -102,6 +104,7 @@ SOURCES += \
dfg/DFGOSRExitCompiler32_64.cpp \
dfg/DFGPhase.cpp \
dfg/DFGPredictionPropagationPhase.cpp \
+ dfg/DFGRedundantPhiEliminationPhase.cpp \
dfg/DFGRepatch.cpp \
dfg/DFGSpeculativeJIT.cpp \
dfg/DFGSpeculativeJIT32_64.cpp \
diff --git a/Source/JavaScriptCore/assembler/ARMAssembler.cpp b/Source/JavaScriptCore/assembler/ARMAssembler.cpp
index 4ded0e88e..b880f50bf 100644
--- a/Source/JavaScriptCore/assembler/ARMAssembler.cpp
+++ b/Source/JavaScriptCore/assembler/ARMAssembler.cpp
@@ -344,14 +344,14 @@ void ARMAssembler::doubleTransfer(bool isLoad, FPRegisterID srcDst, RegisterID b
fdtr_u(isLoad, srcDst, ARMRegisters::S0, 0);
}
-PassRefPtr<ExecutableMemoryHandle> ARMAssembler::executableCopy(JSGlobalData& globalData, void* ownerUID)
+PassRefPtr<ExecutableMemoryHandle> ARMAssembler::executableCopy(JSGlobalData& globalData, void* ownerUID, JITCompilationEffort effort)
{
// 64-bit alignment is required for next constant pool and JIT code as well
m_buffer.flushWithoutBarrier(true);
if (!m_buffer.isAligned(8))
bkpt(0);
- RefPtr<ExecutableMemoryHandle> result = m_buffer.executableCopy(globalData, ownerUID);
+ RefPtr<ExecutableMemoryHandle> result = m_buffer.executableCopy(globalData, ownerUID, effort);
char* data = reinterpret_cast<char*>(result->start());
for (Jumps::Iterator iter = m_jumps.begin(); iter != m_jumps.end(); ++iter) {
diff --git a/Source/JavaScriptCore/assembler/ARMAssembler.h b/Source/JavaScriptCore/assembler/ARMAssembler.h
index ef199d2d1..a9ecf5091 100644
--- a/Source/JavaScriptCore/assembler/ARMAssembler.h
+++ b/Source/JavaScriptCore/assembler/ARMAssembler.h
@@ -30,6 +30,7 @@
#if ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL)
#include "AssemblerBufferWithConstantPool.h"
+#include "JITCompilationEffort.h"
#include <wtf/Assertions.h>
namespace JSC {
@@ -679,7 +680,7 @@ namespace JSC {
return loadBranchTarget(ARMRegisters::pc, cc, useConstantPool);
}
- PassRefPtr<ExecutableMemoryHandle> executableCopy(JSGlobalData&, void* ownerUID);
+ PassRefPtr<ExecutableMemoryHandle> executableCopy(JSGlobalData&, void* ownerUID, JITCompilationEffort);
unsigned debugOffset() { return m_buffer.debugOffset(); }
diff --git a/Source/JavaScriptCore/assembler/ARMv7Assembler.h b/Source/JavaScriptCore/assembler/ARMv7Assembler.h
index 5f376bf3d..51788da08 100644
--- a/Source/JavaScriptCore/assembler/ARMv7Assembler.h
+++ b/Source/JavaScriptCore/assembler/ARMv7Assembler.h
@@ -584,6 +584,7 @@ private:
OP_VMOV_T2 = 0xEEB0,
OP_VMOV_IMM_T2 = 0xEEB0,
OP_VMRS = 0xEEB0,
+ OP_VNEG_T2 = 0xEEB0,
OP_VSQRT_T1 = 0xEEB0,
OP_B_T3a = 0xF000,
OP_B_T4a = 0xF000,
@@ -601,6 +602,7 @@ private:
OP_SUB_S_imm_T3 = 0xF1B0,
OP_CMP_imm_T2 = 0xF1B0,
OP_RSB_imm_T2 = 0xF1C0,
+ OP_RSB_S_imm_T2 = 0xF1D0,
OP_ADD_imm_T4 = 0xF200,
OP_MOV_imm_T3 = 0xF240,
OP_SUB_imm_T4 = 0xF2A0,
@@ -649,6 +651,7 @@ private:
OP_VABS_T2b = 0x0A40,
OP_VCMPb = 0x0A40,
OP_VCVT_FPIVFPb = 0x0A40,
+ OP_VNEG_T2b = 0x0A40,
OP_VSUB_T2b = 0x0A40,
OP_VSQRT_T1b = 0x0A40,
OP_NOP_T2b = 0x8000,
@@ -1584,6 +1587,16 @@ public:
m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_SUB_S_imm_T3, rn, rd, imm);
}
+ ALWAYS_INLINE void sub_S(RegisterID rd, ARMThumbImmediate imm, RegisterID rn)
+ {
+ ASSERT(rd != ARMRegisters::pc);
+ ASSERT(rn != ARMRegisters::pc);
+ ASSERT(imm.isValid());
+ ASSERT(imm.isUInt12());
+
+ m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_RSB_S_imm_T2, rn, rd, imm);
+ }
+
// Not allowed in an IT (if then) block?
ALWAYS_INLINE void sub_S(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift)
{
@@ -1734,6 +1747,11 @@ public:
m_formatter.vfpOp(OP_VABS_T2, OP_VABS_T2b, true, VFPOperand(16), rd, rm);
}
+ void vneg(FPDoubleRegisterID rd, FPDoubleRegisterID rm)
+ {
+ m_formatter.vfpOp(OP_VNEG_T2, OP_VNEG_T2b, true, VFPOperand(1), rd, rm);
+ }
+
void vsqrt(FPDoubleRegisterID rd, FPDoubleRegisterID rm)
{
m_formatter.vfpOp(OP_VSQRT_T1, OP_VSQRT_T1b, true, VFPOperand(17), rd, rm);
diff --git a/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h b/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h
index b4262e894..ab343977e 100644
--- a/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h
+++ b/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h
@@ -28,11 +28,21 @@
#include "CodeLocation.h"
#include "MacroAssemblerCodeRef.h"
+#include <wtf/CryptographicallyRandomNumber.h>
#include <wtf/Noncopyable.h>
#include <wtf/UnusedParam.h>
#if ENABLE(ASSEMBLER)
+
+#if PLATFORM(QT)
+#define ENABLE_JIT_CONSTANT_BLINDING 0
+#endif
+
+#ifndef ENABLE_JIT_CONSTANT_BLINDING
+#define ENABLE_JIT_CONSTANT_BLINDING 1
+#endif
+
namespace JSC {
class LinkBuffer;
@@ -186,11 +196,19 @@ public:
const void* m_value;
};
- struct ImmPtr : public TrustedImmPtr {
+ struct ImmPtr :
+#if ENABLE(JIT_CONSTANT_BLINDING)
+ private TrustedImmPtr
+#else
+ public TrustedImmPtr
+#endif
+ {
explicit ImmPtr(const void* value)
: TrustedImmPtr(value)
{
}
+
+ TrustedImmPtr asTrustedImmPtr() { return *this; }
};
// TrustedImm32:
@@ -232,7 +250,13 @@ public:
};
- struct Imm32 : public TrustedImm32 {
+ struct Imm32 :
+#if ENABLE(JIT_CONSTANT_BLINDING)
+ private TrustedImm32
+#else
+ public TrustedImm32
+#endif
+ {
explicit Imm32(int32_t value)
: TrustedImm32(value)
{
@@ -243,6 +267,8 @@ public:
{
}
#endif
+ const TrustedImm32& asTrustedImm32() const { return *this; }
+
};
// Section 2: MacroAssembler code buffer handles
@@ -535,14 +561,41 @@ public:
return reinterpret_cast<ptrdiff_t>(b.executableAddress()) - reinterpret_cast<ptrdiff_t>(a.executableAddress());
}
- void beginUninterruptedSequence() { }
- void endUninterruptedSequence() { }
+ void beginUninterruptedSequence() { m_inUninterruptedSequence = true; }
+ void endUninterruptedSequence() { m_inUninterruptedSequence = false; }
unsigned debugOffset() { return m_assembler.debugOffset(); }
protected:
+ AbstractMacroAssembler()
+ : m_inUninterruptedSequence(false)
+ , m_randomSource(cryptographicallyRandomNumber())
+ {
+ }
+
AssemblerType m_assembler;
+ bool inUninterruptedSequence()
+ {
+ return m_inUninterruptedSequence;
+ }
+
+ bool m_inUninterruptedSequence;
+
+
+ uint32_t random()
+ {
+ return m_randomSource.getUint32();
+ }
+
+ WeakRandom m_randomSource;
+
+#if ENABLE(JIT_CONSTANT_BLINDING)
+ static bool scratchRegisterForBlinding() { return false; }
+ static bool shouldBlindForSpecificArch(uint32_t) { return true; }
+ static bool shouldBlindForSpecificArch(uint64_t) { return true; }
+#endif
+
friend class LinkBuffer;
friend class RepatchBuffer;
diff --git a/Source/JavaScriptCore/assembler/AssemblerBuffer.h b/Source/JavaScriptCore/assembler/AssemblerBuffer.h
index 55706c1ab..d1deef234 100644
--- a/Source/JavaScriptCore/assembler/AssemblerBuffer.h
+++ b/Source/JavaScriptCore/assembler/AssemblerBuffer.h
@@ -28,6 +28,7 @@
#if ENABLE(ASSEMBLER)
+#include "JITCompilationEffort.h"
#include "JSGlobalData.h"
#include "stdint.h"
#include <string.h>
@@ -129,12 +130,12 @@ namespace JSC {
return AssemblerLabel(m_index);
}
- PassRefPtr<ExecutableMemoryHandle> executableCopy(JSGlobalData& globalData, void* ownerUID)
+ PassRefPtr<ExecutableMemoryHandle> executableCopy(JSGlobalData& globalData, void* ownerUID, JITCompilationEffort effort)
{
if (!m_index)
return 0;
- RefPtr<ExecutableMemoryHandle> result = globalData.executableAllocator.allocate(globalData, m_index, ownerUID);
+ RefPtr<ExecutableMemoryHandle> result = globalData.executableAllocator.allocate(globalData, m_index, ownerUID, effort);
if (!result)
return 0;
diff --git a/Source/JavaScriptCore/assembler/AssemblerBufferWithConstantPool.h b/Source/JavaScriptCore/assembler/AssemblerBufferWithConstantPool.h
index 68afa766b..e2ea261ee 100644
--- a/Source/JavaScriptCore/assembler/AssemblerBufferWithConstantPool.h
+++ b/Source/JavaScriptCore/assembler/AssemblerBufferWithConstantPool.h
@@ -195,10 +195,10 @@ public:
putIntegralUnchecked(value.low);
}
- PassRefPtr<ExecutableMemoryHandle> executableCopy(JSGlobalData& globalData, void* ownerUID)
+ PassRefPtr<ExecutableMemoryHandle> executableCopy(JSGlobalData& globalData, void* ownerUID, JITCompilationEffort effort)
{
flushConstantPool(false);
- return AssemblerBuffer::executableCopy(globalData, ownerUID);
+ return AssemblerBuffer::executableCopy(globalData, ownerUID, effort);
}
void putShortWithConstantInt(uint16_t insn, uint32_t constant, bool isReusable = false)
diff --git a/Source/JavaScriptCore/assembler/LinkBuffer.h b/Source/JavaScriptCore/assembler/LinkBuffer.h
index 2c07d13fc..6ec9a7eb9 100644
--- a/Source/JavaScriptCore/assembler/LinkBuffer.h
+++ b/Source/JavaScriptCore/assembler/LinkBuffer.h
@@ -34,6 +34,7 @@
#define GLOBAL_THUNK_ID reinterpret_cast<void*>(static_cast<intptr_t>(-1))
#define REGEXP_CODE_ID reinterpret_cast<void*>(static_cast<intptr_t>(-2))
+#include "JITCompilationEffort.h"
#include "MacroAssembler.h"
#include <wtf/DataLog.h>
#include <wtf/Noncopyable.h>
@@ -73,7 +74,7 @@ class LinkBuffer {
#endif
public:
- LinkBuffer(JSGlobalData& globalData, MacroAssembler* masm, void* ownerUID)
+ LinkBuffer(JSGlobalData& globalData, MacroAssembler* masm, void* ownerUID, JITCompilationEffort effort = JITCompilationMustSucceed)
: m_size(0)
#if ENABLE(BRANCH_COMPACTION)
, m_initialSize(0)
@@ -83,16 +84,27 @@ public:
, m_globalData(&globalData)
#ifndef NDEBUG
, m_completed(false)
+ , m_effort(effort)
#endif
{
- linkCode(ownerUID);
+ linkCode(ownerUID, effort);
}
~LinkBuffer()
{
- ASSERT(m_completed);
+ ASSERT(m_completed || (!m_executableMemory && m_effort == JITCompilationCanFail));
+ }
+
+ bool didFailToAllocate() const
+ {
+ return !m_executableMemory;
}
+ bool isValid() const
+ {
+ return !didFailToAllocate();
+ }
+
// These methods are used to link or set values at code generation time.
void link(Call call, FunctionPtr function)
@@ -218,11 +230,11 @@ private:
return m_code;
}
- void linkCode(void* ownerUID)
+ void linkCode(void* ownerUID, JITCompilationEffort effort)
{
ASSERT(!m_code);
#if !ENABLE(BRANCH_COMPACTION)
- m_executableMemory = m_assembler->m_assembler.executableCopy(*m_globalData, ownerUID);
+ m_executableMemory = m_assembler->m_assembler.executableCopy(*m_globalData, ownerUID, effort);
if (!m_executableMemory)
return;
m_code = m_executableMemory->start();
@@ -230,7 +242,7 @@ private:
ASSERT(m_code);
#else
m_initialSize = m_assembler->m_assembler.codeSize();
- m_executableMemory = m_globalData->executableAllocator.allocate(*m_globalData, m_initialSize, ownerUID);
+ m_executableMemory = m_globalData->executableAllocator.allocate(*m_globalData, m_initialSize, ownerUID, effort);
if (!m_executableMemory)
return;
m_code = (uint8_t*)m_executableMemory->start();
@@ -307,6 +319,7 @@ private:
{
#ifndef NDEBUG
ASSERT(!m_completed);
+ ASSERT(isValid());
m_completed = true;
#endif
@@ -375,6 +388,7 @@ private:
JSGlobalData* m_globalData;
#ifndef NDEBUG
bool m_completed;
+ JITCompilationEffort m_effort;
#endif
};
diff --git a/Source/JavaScriptCore/assembler/MIPSAssembler.h b/Source/JavaScriptCore/assembler/MIPSAssembler.h
index b59fa0b8f..5e0645129 100644
--- a/Source/JavaScriptCore/assembler/MIPSAssembler.h
+++ b/Source/JavaScriptCore/assembler/MIPSAssembler.h
@@ -32,6 +32,7 @@
#if ENABLE(ASSEMBLER) && CPU(MIPS)
#include "AssemblerBuffer.h"
+#include "JITCompilationEffort.h"
#include <wtf/Assertions.h>
#include <wtf/SegmentedVector.h>
@@ -645,9 +646,9 @@ public:
return m_buffer.codeSize();
}
- PassRefPtr<ExecutableMemoryHandle> executableCopy(JSGlobalData& globalData, void* ownerUID)
+ PassRefPtr<ExecutableMemoryHandle> executableCopy(JSGlobalData& globalData, void* ownerUID, JITCompilationEffort effort)
{
- RefPtr<ExecutableMemoryHandle> result = m_buffer.executableCopy(globalData, ownerUID);
+ RefPtr<ExecutableMemoryHandle> result = m_buffer.executableCopy(globalData, ownerUID, effort);
if (!result)
return 0;
diff --git a/Source/JavaScriptCore/assembler/MacroAssembler.h b/Source/JavaScriptCore/assembler/MacroAssembler.h
index 347cd0ea0..4c54e29aa 100644
--- a/Source/JavaScriptCore/assembler/MacroAssembler.h
+++ b/Source/JavaScriptCore/assembler/MacroAssembler.h
@@ -60,7 +60,6 @@ typedef MacroAssemblerSH4 MacroAssemblerBase;
#error "The MacroAssembler is not supported on this platform."
#endif
-
namespace JSC {
class MacroAssembler : public MacroAssemblerBase {
@@ -73,6 +72,22 @@ public:
using MacroAssemblerBase::branchPtr;
using MacroAssemblerBase::branchTestPtr;
#endif
+ using MacroAssemblerBase::move;
+
+#if ENABLE(JIT_CONSTANT_BLINDING)
+ using MacroAssemblerBase::add32;
+ using MacroAssemblerBase::and32;
+ using MacroAssemblerBase::branchAdd32;
+ using MacroAssemblerBase::branchMul32;
+ using MacroAssemblerBase::branchSub32;
+ using MacroAssemblerBase::lshift32;
+ using MacroAssemblerBase::or32;
+ using MacroAssemblerBase::rshift32;
+ using MacroAssemblerBase::store32;
+ using MacroAssemblerBase::sub32;
+ using MacroAssemblerBase::urshift32;
+ using MacroAssemblerBase::xor32;
+#endif
// Utilities used by the DFG JIT.
#if ENABLE(DFG_JIT)
@@ -148,19 +163,24 @@ public:
loadPtr(Address(stackPointerRegister, (index * sizeof(void*))), dest);
}
+ Address addressForPoke(int index)
+ {
+ return Address(stackPointerRegister, (index * sizeof(void*)));
+ }
+
void poke(RegisterID src, int index = 0)
{
- storePtr(src, Address(stackPointerRegister, (index * sizeof(void*))));
+ storePtr(src, addressForPoke(index));
}
void poke(TrustedImm32 value, int index = 0)
{
- store32(value, Address(stackPointerRegister, (index * sizeof(void*))));
+ store32(value, addressForPoke(index));
}
void poke(TrustedImmPtr imm, int index = 0)
{
- storePtr(imm, Address(stackPointerRegister, (index * sizeof(void*))));
+ storePtr(imm, addressForPoke(index));
}
@@ -169,6 +189,10 @@ public:
{
branchPtr(cond, op1, imm).linkTo(target, this);
}
+ void branchPtr(RelationalCondition cond, RegisterID op1, ImmPtr imm, Label target)
+ {
+ branchPtr(cond, op1, imm).linkTo(target, this);
+ }
void branch32(RelationalCondition cond, RegisterID op1, RegisterID op2, Label target)
{
@@ -179,6 +203,11 @@ public:
{
branch32(cond, op1, imm).linkTo(target, this);
}
+
+ void branch32(RelationalCondition cond, RegisterID op1, Imm32 imm, Label target)
+ {
+ branch32(cond, op1, imm).linkTo(target, this);
+ }
void branch32(RelationalCondition cond, RegisterID left, Address right, Label target)
{
@@ -190,6 +219,11 @@ public:
return branch32(commute(cond), right, left);
}
+ Jump branch32(RelationalCondition cond, Imm32 left, RegisterID right)
+ {
+ return branch32(commute(cond), right, left);
+ }
+
void branchTestPtr(ResultCondition cond, RegisterID reg, Label target)
{
branchTestPtr(cond, reg).linkTo(target, this);
@@ -340,6 +374,11 @@ public:
return load32WithCompactAddressOffsetPatch(address, dest);
}
+ void move(ImmPtr imm, RegisterID dest)
+ {
+ move(Imm32(imm.asTrustedImmPtr()), dest);
+ }
+
void comparePtr(RelationalCondition cond, RegisterID left, TrustedImm32 right, RegisterID dest)
{
compare32(cond, left, right, dest);
@@ -364,6 +403,11 @@ public:
{
store32(TrustedImm32(imm), address);
}
+
+ void storePtr(ImmPtr imm, Address address)
+ {
+ store32(Imm32(imm.asTrustedImmPtr()), address);
+ }
void storePtr(TrustedImmPtr imm, void* address)
{
@@ -375,7 +419,6 @@ public:
return store32WithAddressOffsetPatch(src, address);
}
-
Jump branchPtr(RelationalCondition cond, RegisterID left, RegisterID right)
{
return branch32(cond, left, right);
@@ -385,6 +428,11 @@ public:
{
return branch32(cond, left, TrustedImm32(right));
}
+
+ Jump branchPtr(RelationalCondition cond, RegisterID left, ImmPtr right)
+ {
+ return branch32(cond, left, Imm32(right.asTrustedImmPtr()));
+ }
Jump branchPtr(RelationalCondition cond, RegisterID left, Address right)
{
@@ -405,7 +453,7 @@ public:
{
return branch32(cond, left, TrustedImm32(right));
}
-
+
Jump branchPtr(RelationalCondition cond, AbsoluteAddress left, TrustedImmPtr right)
{
return branch32(cond, left, TrustedImm32(right));
@@ -431,7 +479,6 @@ public:
return branchTest32(cond, address, mask);
}
-
Jump branchAddPtr(ResultCondition cond, RegisterID src, RegisterID dest)
{
return branchAdd32(cond, src, dest);
@@ -446,8 +493,499 @@ public:
{
return MacroAssemblerBase::branchTest8(cond, Address(address.base, address.offset), mask);
}
+#else
+
+#if ENABLE(JIT_CONSTANT_BLINDING)
+ using MacroAssemblerBase::addPtr;
+ using MacroAssemblerBase::andPtr;
+ using MacroAssemblerBase::branchSubPtr;
+ using MacroAssemblerBase::convertInt32ToDouble;
+ using MacroAssemblerBase::storePtr;
+ using MacroAssemblerBase::subPtr;
+ using MacroAssemblerBase::xorPtr;
+
+ bool shouldBlindDouble(double value)
+ {
+ // Don't trust NaN or +/-Infinity
+ if (!isfinite(value))
+ return true;
+
+ // Try to force normalisation, and check that there's no change
+ // in the bit pattern
+ if (bitwise_cast<uintptr_t>(value * 1.0) != bitwise_cast<uintptr_t>(value))
+ return true;
+
+ value = abs(value);
+ // Only allow a limited set of fractional components
+ double scaledValue = value * 8;
+ if (scaledValue / 8 != value)
+ return true;
+ double frac = scaledValue - floor(scaledValue);
+ if (frac != 0.0)
+ return true;
+
+ return value > 0xff;
+ }
+
+ bool shouldBlind(ImmPtr imm)
+ {
+ ASSERT(!inUninterruptedSequence());
+#if !defined(NDEBUG)
+ UNUSED_PARAM(imm);
+ // Debug always blind all constants, if only so we know
+ // if we've broken blinding during patch development.
+ return true;
+#endif
+
+ // First off we'll special case common, "safe" values to avoid hurting
+ // performance too much
+ uintptr_t value = imm.asTrustedImmPtr().asIntptr();
+ switch (value) {
+ case 0xffff:
+ case 0xffffff:
+ case 0xffffffffL:
+ case 0xffffffffffL:
+ case 0xffffffffffffL:
+ case 0xffffffffffffffL:
+ case 0xffffffffffffffffL:
+ return false;
+ default: {
+ if (value <= 0xff)
+ return false;
+#if CPU(X86_64)
+ JSValue jsValue = JSValue::decode(reinterpret_cast<void*>(value));
+ if (jsValue.isInt32())
+ return shouldBlind(Imm32(jsValue.asInt32()));
+ if (jsValue.isDouble() && !shouldBlindDouble(jsValue.asDouble()))
+ return false;
+
+ if (!shouldBlindDouble(bitwise_cast<double>(value)))
+ return false;
+#endif
+ }
+ }
+ return shouldBlindForSpecificArch(value);
+ }
+
+ struct RotatedImmPtr {
+ RotatedImmPtr(uintptr_t v1, uint8_t v2)
+ : value(v1)
+ , rotation(v2)
+ {
+ }
+ TrustedImmPtr value;
+ TrustedImm32 rotation;
+ };
+
+ RotatedImmPtr rotationBlindConstant(ImmPtr imm)
+ {
+ uint8_t rotation = random() % (sizeof(void*) * 8);
+ uintptr_t value = imm.asTrustedImmPtr().asIntptr();
+ value = (value << rotation) | (value >> (sizeof(void*) * 8 - rotation));
+ return RotatedImmPtr(value, rotation);
+ }
+
+ void loadRotationBlindedConstant(RotatedImmPtr constant, RegisterID dest)
+ {
+ move(constant.value, dest);
+ rotateRightPtr(constant.rotation, dest);
+ }
+
+ void convertInt32ToDouble(Imm32 imm, FPRegisterID dest)
+ {
+ if (shouldBlind(imm)) {
+ RegisterID scratchRegister = scratchRegisterForBlinding();
+ loadXorBlindedConstant(xorBlindConstant(imm), scratchRegister);
+ convertInt32ToDouble(scratchRegister, dest);
+ } else
+ convertInt32ToDouble(imm.asTrustedImm32(), dest);
+ }
+
+ void move(ImmPtr imm, RegisterID dest)
+ {
+ if (shouldBlind(imm))
+ loadRotationBlindedConstant(rotationBlindConstant(imm), dest);
+ else
+ move(imm.asTrustedImmPtr(), dest);
+ }
+
+ Jump branchPtr(RelationalCondition cond, RegisterID left, ImmPtr right)
+ {
+ if (shouldBlind(right)) {
+ RegisterID scratchRegister = scratchRegisterForBlinding();
+ loadRotationBlindedConstant(rotationBlindConstant(right), scratchRegister);
+ return branchPtr(cond, left, scratchRegister);
+ }
+ return branchPtr(cond, left, right.asTrustedImmPtr());
+ }
+
+ void storePtr(ImmPtr imm, Address dest)
+ {
+ if (shouldBlind(imm)) {
+ RegisterID scratchRegister = scratchRegisterForBlinding();
+ loadRotationBlindedConstant(rotationBlindConstant(imm), scratchRegister);
+ storePtr(scratchRegister, dest);
+ } else
+ storePtr(imm.asTrustedImmPtr(), dest);
+ }
+
+#endif
+
#endif // !CPU(X86_64)
+#if ENABLE(JIT_CONSTANT_BLINDING)
+ bool shouldBlind(Imm32 imm)
+ {
+ ASSERT(!inUninterruptedSequence());
+#if !defined(NDEBUG)
+ UNUSED_PARAM(imm);
+ // Debug always blind all constants, if only so we know
+ // if we've broken blinding during patch development.
+ return true;
+#else
+
+ // First off we'll special case common, "safe" values to avoid hurting
+ // performance too much
+ uint32_t value = imm.asTrustedImm32().m_value;
+ switch (value) {
+ case 0xffff:
+ case 0xffffff:
+ case 0xffffffff:
+ return false;
+ default:
+ if (value <= 0xff)
+ return false;
+ }
+ return shouldBlindForSpecificArch(value);
+#endif
+ }
+
+ struct BlindedImm32 {
+ BlindedImm32(int32_t v1, int32_t v2)
+ : value1(v1)
+ , value2(v2)
+ {
+ }
+ TrustedImm32 value1;
+ TrustedImm32 value2;
+ };
+
+ uint32_t keyForConstant(uint32_t value, uint32_t& mask)
+ {
+ uint32_t key = random();
+ if (value <= 0xff)
+ mask = 0xff;
+ else if (value <= 0xffff)
+ mask = 0xffff;
+ else if (value <= 0xffffff)
+ mask = 0xffffff;
+ else
+ mask = 0xffffffff;
+ return key & mask;
+ }
+
+ uint32_t keyForConstant(uint32_t value)
+ {
+ uint32_t mask = 0;
+ return keyForConstant(value, mask);
+ }
+
+ BlindedImm32 xorBlindConstant(Imm32 imm)
+ {
+ uint32_t baseValue = imm.asTrustedImm32().m_value;
+ uint32_t key = keyForConstant(baseValue);
+ return BlindedImm32(baseValue ^ key, key);
+ }
+
+ BlindedImm32 additionBlindedConstant(Imm32 imm)
+ {
+ uint32_t baseValue = imm.asTrustedImm32().m_value;
+ uint32_t key = keyForConstant(baseValue);
+ if (key > baseValue)
+ key = key - baseValue;
+ return BlindedImm32(baseValue - key, key);
+ }
+
+ BlindedImm32 andBlindedConstant(Imm32 imm)
+ {
+ uint32_t baseValue = imm.asTrustedImm32().m_value;
+ uint32_t mask = 0;
+ uint32_t key = keyForConstant(baseValue, mask);
+ ASSERT((baseValue & mask) == baseValue);
+ return BlindedImm32(((baseValue & key) | ~key) & mask, ((baseValue & ~key) | key) & mask);
+ }
+
+ BlindedImm32 orBlindedConstant(Imm32 imm)
+ {
+ uint32_t baseValue = imm.asTrustedImm32().m_value;
+ uint32_t mask = 0;
+ uint32_t key = keyForConstant(baseValue, mask);
+ ASSERT((baseValue & mask) == baseValue);
+ return BlindedImm32((baseValue & key) & mask, (baseValue & ~key) & mask);
+ }
+
+ void loadXorBlindedConstant(BlindedImm32 constant, RegisterID dest)
+ {
+ move(constant.value1, dest);
+ xor32(constant.value2, dest);
+ }
+
+ void add32(Imm32 imm, RegisterID dest)
+ {
+ if (shouldBlind(imm)) {
+ BlindedImm32 key = additionBlindedConstant(imm);
+ add32(key.value1, dest);
+ add32(key.value2, dest);
+ } else
+ add32(imm.asTrustedImm32(), dest);
+ }
+
+ void addPtr(Imm32 imm, RegisterID dest)
+ {
+ if (shouldBlind(imm)) {
+ BlindedImm32 key = additionBlindedConstant(imm);
+ addPtr(key.value1, dest);
+ addPtr(key.value2, dest);
+ } else
+ addPtr(imm.asTrustedImm32(), dest);
+ }
+
+ void and32(Imm32 imm, RegisterID dest)
+ {
+ if (shouldBlind(imm)) {
+ BlindedImm32 key = andBlindedConstant(imm);
+ and32(key.value1, dest);
+ and32(key.value2, dest);
+ } else
+ and32(imm.asTrustedImm32(), dest);
+ }
+
+ void andPtr(Imm32 imm, RegisterID dest)
+ {
+ if (shouldBlind(imm)) {
+ BlindedImm32 key = andBlindedConstant(imm);
+ andPtr(key.value1, dest);
+ andPtr(key.value2, dest);
+ } else
+ andPtr(imm.asTrustedImm32(), dest);
+ }
+
+ void and32(Imm32 imm, RegisterID src, RegisterID dest)
+ {
+ if (shouldBlind(imm)) {
+ if (src == dest)
+ return and32(imm.asTrustedImm32(), dest);
+ loadXorBlindedConstant(xorBlindConstant(imm), dest);
+ and32(src, dest);
+ } else
+ and32(imm.asTrustedImm32(), src, dest);
+ }
+
+ void move(Imm32 imm, RegisterID dest)
+ {
+ if (shouldBlind(imm))
+ loadXorBlindedConstant(xorBlindConstant(imm), dest);
+ else
+ move(imm.asTrustedImm32(), dest);
+ }
+
+ void or32(Imm32 imm, RegisterID src, RegisterID dest)
+ {
+ if (shouldBlind(imm)) {
+ if (src == dest)
+ return or32(imm, dest);
+ loadXorBlindedConstant(xorBlindConstant(imm), dest);
+ or32(src, dest);
+ } else
+ or32(imm.asTrustedImm32(), src, dest);
+ }
+
+ void or32(Imm32 imm, RegisterID dest)
+ {
+ if (shouldBlind(imm)) {
+ BlindedImm32 key = orBlindedConstant(imm);
+ or32(key.value1, dest);
+ or32(key.value2, dest);
+ } else
+ or32(imm.asTrustedImm32(), dest);
+ }
+
+ void poke(Imm32 value, int index = 0)
+ {
+ store32(value, addressForPoke(index));
+ }
+
+ void poke(ImmPtr value, int index = 0)
+ {
+ storePtr(value, addressForPoke(index));
+ }
+
+ void store32(Imm32 imm, Address dest)
+ {
+ if (shouldBlind(imm)) {
+#if CPU(X86) || CPU(X86_64)
+ BlindedImm32 blind = xorBlindConstant(imm);
+ store32(blind.value1, dest);
+ xor32(blind.value2, dest);
+#else
+ RegisterID scratchRegister = (RegisterID)scratchRegisterForBlinding();
+ loadXorBlindedConstant(xorBlindConstant(imm), scratchRegister);
+ store32(scratchRegister, dest);
+#endif
+ } else
+ store32(imm.asTrustedImm32(), dest);
+ }
+
+ void sub32(Imm32 imm, RegisterID dest)
+ {
+ if (shouldBlind(imm)) {
+ BlindedImm32 key = additionBlindedConstant(imm);
+ sub32(key.value1, dest);
+ sub32(key.value2, dest);
+ } else
+ sub32(imm.asTrustedImm32(), dest);
+ }
+
+ void subPtr(Imm32 imm, RegisterID dest)
+ {
+ if (shouldBlind(imm)) {
+ BlindedImm32 key = additionBlindedConstant(imm);
+ subPtr(key.value1, dest);
+ subPtr(key.value2, dest);
+ } else
+ subPtr(imm.asTrustedImm32(), dest);
+ }
+
+ void xor32(Imm32 imm, RegisterID src, RegisterID dest)
+ {
+ if (shouldBlind(imm)) {
+ BlindedImm32 blind = xorBlindConstant(imm);
+ xor32(blind.value1, src, dest);
+ xor32(blind.value2, dest);
+ } else
+ xor32(imm.asTrustedImm32(), src, dest);
+ }
+
+ void xor32(Imm32 imm, RegisterID dest)
+ {
+ if (shouldBlind(imm)) {
+ BlindedImm32 blind = xorBlindConstant(imm);
+ xor32(blind.value1, dest);
+ xor32(blind.value2, dest);
+ } else
+ xor32(imm.asTrustedImm32(), dest);
+ }
+
+ Jump branch32(RelationalCondition cond, RegisterID left, Imm32 right)
+ {
+ if (shouldBlind(right)) {
+ if (RegisterID scratchRegister = (RegisterID)scratchRegisterForBlinding()) {
+ loadXorBlindedConstant(xorBlindConstant(right), scratchRegister);
+ return branch32(cond, left, scratchRegister);
+ }
+ // If we don't have a scratch register available for use, we'll just
+ // place a random number of nops.
+ uint32_t nopCount = random() & 3;
+ while (nopCount--)
+ nop();
+ return branch32(cond, left, right.asTrustedImm32());
+ }
+
+ return branch32(cond, left, right.asTrustedImm32());
+ }
+
+ Jump branchAdd32(ResultCondition cond, RegisterID src, Imm32 imm, RegisterID dest)
+ {
+ if (src == dest) {
+ if (!scratchRegisterForBlinding()) {
+ // Release mode ASSERT, if this fails we will perform incorrect codegen.
+ CRASH();
+ }
+ }
+ if (shouldBlind(imm)) {
+ if (src == dest) {
+ if (RegisterID scratchRegister = (RegisterID)scratchRegisterForBlinding()) {
+ move(src, scratchRegister);
+ src = scratchRegister;
+ }
+ }
+ loadXorBlindedConstant(xorBlindConstant(imm), dest);
+ return branchAdd32(cond, src, dest);
+ }
+ return branchAdd32(cond, src, imm.asTrustedImm32(), dest);
+ }
+
+ Jump branchMul32(ResultCondition cond, Imm32 imm, RegisterID src, RegisterID dest)
+ {
+ if (src == dest) {
+ if (!scratchRegisterForBlinding()) {
+ // Release mode ASSERT, if this fails we will perform incorrect codegen.
+ CRASH();
+ }
+ }
+ if (shouldBlind(imm)) {
+ if (src == dest) {
+ if (RegisterID scratchRegister = (RegisterID)scratchRegisterForBlinding()) {
+ move(src, scratchRegister);
+ src = scratchRegister;
+ }
+ }
+ loadXorBlindedConstant(xorBlindConstant(imm), dest);
+ return branchMul32(cond, src, dest);
+ }
+ return branchMul32(cond, imm.asTrustedImm32(), src, dest);
+ }
+
+ // branchSub32 takes a scratch register as 32 bit platforms make use of this,
+ // with src == dst, and on x86-32 we don't have a platform scratch register.
+ Jump branchSub32(ResultCondition cond, RegisterID src, Imm32 imm, RegisterID dest, RegisterID scratch)
+ {
+ if (shouldBlind(imm)) {
+ ASSERT(scratch != dest);
+ ASSERT(scratch != src);
+ loadXorBlindedConstant(xorBlindConstant(imm), scratch);
+ return branchSub32(cond, src, scratch, dest);
+ }
+ return branchSub32(cond, src, imm.asTrustedImm32(), dest);
+ }
+
+ // Immediate shifts only have 5 controllable bits
+ // so we'll consider them safe for now.
+ TrustedImm32 trustedImm32ForShift(Imm32 imm)
+ {
+ return TrustedImm32(imm.asTrustedImm32().m_value & 31);
+ }
+
+ void lshift32(Imm32 imm, RegisterID dest)
+ {
+ lshift32(trustedImm32ForShift(imm), dest);
+ }
+
+ void lshift32(RegisterID src, Imm32 amount, RegisterID dest)
+ {
+ lshift32(src, trustedImm32ForShift(amount), dest);
+ }
+
+ void rshift32(Imm32 imm, RegisterID dest)
+ {
+ rshift32(trustedImm32ForShift(imm), dest);
+ }
+
+ void rshift32(RegisterID src, Imm32 amount, RegisterID dest)
+ {
+ rshift32(src, trustedImm32ForShift(amount), dest);
+ }
+
+ void urshift32(Imm32 imm, RegisterID dest)
+ {
+ urshift32(trustedImm32ForShift(imm), dest);
+ }
+
+ void urshift32(RegisterID src, Imm32 amount, RegisterID dest)
+ {
+ urshift32(src, trustedImm32ForShift(amount), dest);
+ }
+#endif
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARM.h b/Source/JavaScriptCore/assembler/MacroAssemblerARM.h
index 51173895a..c0cd766cb 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerARM.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerARM.h
@@ -108,6 +108,11 @@ public:
add32(ARMRegisters::S1, dest);
}
+ void add32(RegisterID src, TrustedImm32 imm, RegisterID dest)
+ {
+ m_assembler.adds_r(dest, src, m_assembler.getImm(imm.m_value, ARMRegisters::S0));
+ }
+
void and32(RegisterID src, RegisterID dest)
{
m_assembler.ands_r(dest, dest, src);
@@ -122,6 +127,15 @@ public:
m_assembler.ands_r(dest, dest, w);
}
+ void and32(TrustedImm32 imm, RegisterID src, RegisterID dest)
+ {
+ ARMWord w = m_assembler.getImm(imm.m_value, ARMRegisters::S0, true);
+ if (w & ARMAssembler::OP2_INV_IMM)
+ m_assembler.bics_r(dest, src, w & ~ARMAssembler::OP2_INV_IMM);
+ else
+ m_assembler.ands_r(dest, src, w);
+ }
+
void lshift32(RegisterID shift_amount, RegisterID dest)
{
ARMWord w = ARMAssembler::getOp2(0x1f);
@@ -156,11 +170,6 @@ public:
m_assembler.rsbs_r(srcDest, srcDest, ARMAssembler::getOp2(0));
}
- void not32(RegisterID dest)
- {
- m_assembler.mvns_r(dest, dest);
- }
-
void or32(RegisterID src, RegisterID dest)
{
m_assembler.orrs_r(dest, dest, src);
@@ -232,6 +241,11 @@ public:
sub32(ARMRegisters::S1, dest);
}
+ void sub32(RegisterID src, TrustedImm32 imm, RegisterID dest)
+ {
+ m_assembler.subs_r(dest, src, m_assembler.getImm(imm.m_value, ARMRegisters::S0));
+ }
+
void xor32(RegisterID src, RegisterID dest)
{
m_assembler.eors_r(dest, dest, src);
@@ -239,7 +253,10 @@ public:
void xor32(TrustedImm32 imm, RegisterID dest)
{
- m_assembler.eors_r(dest, dest, m_assembler.getImm(imm.m_value, ARMRegisters::S0));
+ if (imm.m_value == -1)
+ m_assembler.mvns_r(dest, dest);
+ else
+ m_assembler.eors_r(dest, dest, m_assembler.getImm(imm.m_value, ARMRegisters::S0));
}
void countLeadingZeros32(RegisterID src, RegisterID dest)
@@ -547,6 +564,13 @@ public:
return Jump(m_assembler.jmp(ARMCondition(cond)));
}
+ Jump branchAdd32(ResultCondition cond, RegisterID src, TrustedImm32 imm, RegisterID dest)
+ {
+ ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
+ add32(src, imm, dest);
+ return Jump(m_assembler.jmp(ARMCondition(cond)));
+ }
+
void mull32(RegisterID src1, RegisterID src2, RegisterID dest)
{
if (src1 == dest) {
@@ -596,6 +620,13 @@ public:
return Jump(m_assembler.jmp(ARMCondition(cond)));
}
+ Jump branchSub32(ResultCondition cond, RegisterID src, TrustedImm32 imm, RegisterID dest)
+ {
+ ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
+ sub32(src, imm, dest);
+ return Jump(m_assembler.jmp(ARMCondition(cond)));
+ }
+
Jump branchNeg32(ResultCondition cond, RegisterID srcDest)
{
ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
index d883abf4f..43ea2ed5a 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
@@ -51,14 +51,7 @@ public:
// Magic number is the biggest useful offset we can get on ARMv7 with
// a LDR_imm_T2 encoding
static const int MaximumCompactPtrAlignedAddressOffset = 124;
-
- MacroAssemblerARMv7()
- : m_inUninterruptedSequence(false)
- {
- }
- void beginUninterruptedSequence() { m_inUninterruptedSequence = true; }
- void endUninterruptedSequence() { m_inUninterruptedSequence = false; }
Vector<LinkRecord>& jumpsToLink() { return m_assembler.jumpsToLink(); }
void* unlinkedCode() { return m_assembler.unlinkedCode(); }
bool canCompact(JumpType jumpType) { return m_assembler.canCompact(jumpType); }
@@ -303,11 +296,6 @@ public:
m_assembler.neg(srcDest, srcDest);
}
- void not32(RegisterID srcDest)
- {
- m_assembler.mvn(srcDest, srcDest);
- }
-
void or32(RegisterID src, RegisterID dest)
{
m_assembler.orr(dest, dest, src);
@@ -447,6 +435,11 @@ public:
void xor32(TrustedImm32 imm, RegisterID src, RegisterID dest)
{
+ if (imm.m_value == -1) {
+ m_assembler.mvn(dest, src);
+ return;
+ }
+
ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm.m_value);
if (armImm.isValid())
m_assembler.eor(dest, src, armImm);
@@ -463,7 +456,10 @@ public:
void xor32(TrustedImm32 imm, RegisterID dest)
{
- xor32(imm, dest, dest);
+ if (imm.m_value == -1)
+ m_assembler.mvn(dest, dest);
+ else
+ xor32(imm, dest, dest);
}
@@ -527,6 +523,7 @@ private:
unreachableForPlatform();
}
+protected:
void store32(RegisterID src, ArmAddress address)
{
if (address.type == ArmAddress::HasIndex)
@@ -541,6 +538,7 @@ private:
}
}
+private:
void store8(RegisterID src, ArmAddress address)
{
if (address.type == ArmAddress::HasIndex)
@@ -723,6 +721,26 @@ public:
store16(src, setupArmAddress(address));
}
+#if ENABLE(JIT_CONSTANT_BLINDING)
+ static RegisterID scratchRegisterForBlinding() { return dataTempRegister; }
+ static bool shouldBlindForSpecificArch(uint32_t value)
+ {
+ ARMThumbImmediate immediate = ARMThumbImmediate::makeEncodedImm(value);
+
+ // Couldn't be encoded as an immediate, so assume it's untrusted.
+ if (!immediate.isValid())
+ return true;
+
+ // If we can encode the immediate, we have less than 16 attacker
+ // controlled bits.
+ if (immediate.isEncodedImm())
+ return false;
+
+ // Don't let any more than 12 bits of an instruction word
+ // be controlled by an attacker.
+ return !immediate.isUInt12();
+ }
+#endif
// Floating-point operations:
@@ -789,7 +807,7 @@ public:
void storeDouble(FPRegisterID src, const void* address)
{
- move(ImmPtr(address), addressTempRegister);
+ move(TrustedImmPtr(address), addressTempRegister);
storeDouble(src, addressTempRegister);
}
@@ -883,6 +901,11 @@ public:
m_assembler.vabs(dest, src);
}
+ void negateDouble(FPRegisterID src, FPRegisterID dest)
+ {
+ m_assembler.vneg(dest, src);
+ }
+
void convertInt32ToDouble(RegisterID src, FPRegisterID dest)
{
m_assembler.vmov(fpTempRegisterAsSingle(), src);
@@ -954,7 +977,7 @@ public:
// clamped to 0x80000000, so 2x dest is zero in this case. In the case of
// overflow the result will be equal to -2.
Jump underflow = branchAdd32(Zero, dest, dest, dataTempRegister);
- Jump noOverflow = branch32(NotEqual, dataTempRegister, Imm32(-2));
+ Jump noOverflow = branch32(NotEqual, dataTempRegister, TrustedImm32(-2));
// For BranchIfTruncateSuccessful, we branch if 'noOverflow' jumps.
underflow.link(this);
@@ -1356,7 +1379,7 @@ public:
{
// Move the high bits of the address into addressTempRegister,
// and load the value into dataTempRegister.
- move(ImmPtr(dest.m_ptr), addressTempRegister);
+ move(TrustedImmPtr(dest.m_ptr), addressTempRegister);
m_assembler.ldr(dataTempRegister, addressTempRegister, ARMThumbImmediate::makeUInt16(0));
// Do the add.
@@ -1369,7 +1392,7 @@ public:
// we'll need to reload it with the high bits of the address afterwards.
move(imm, addressTempRegister);
m_assembler.add_S(dataTempRegister, dataTempRegister, addressTempRegister);
- move(ImmPtr(dest.m_ptr), addressTempRegister);
+ move(TrustedImmPtr(dest.m_ptr), addressTempRegister);
}
// Store the result.
@@ -1401,6 +1424,13 @@ public:
return branchMul32(cond, dataTempRegister, src, dest);
}
+ Jump branchNeg32(ResultCondition cond, RegisterID srcDest)
+ {
+ ARMThumbImmediate zero = ARMThumbImmediate::makeUInt12(0);
+ m_assembler.sub_S(srcDest, zero, srcDest);
+ return Jump(makeBranch(cond));
+ }
+
Jump branchOr32(ResultCondition cond, RegisterID src, RegisterID dest)
{
m_assembler.orr_S(dest, dest, src);
@@ -1586,10 +1616,6 @@ public:
}
protected:
- bool inUninterruptedSequence()
- {
- return m_inUninterruptedSequence;
- }
ALWAYS_INLINE Jump jump()
{
@@ -1697,8 +1723,7 @@ private:
{
ARMv7Assembler::relinkCall(call.dataLocation(), destination.executableAddress());
}
-
- bool m_inUninterruptedSequence;
+
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h b/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h
index 3d7d84534..ac62c4221 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h
@@ -27,9 +27,9 @@
#define MacroAssemblerCodeRef_h
#include "ExecutableAllocator.h"
-#include "PassRefPtr.h"
-#include "RefPtr.h"
-#include "UnusedParam.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+#include <wtf/UnusedParam.h>
// ASSERT_VALID_CODE_POINTER checks that ptr is a non-null pointer, and that it is a valid
// instruction address on the platform (for example, check any alignment requirements).
@@ -280,6 +280,10 @@ public:
return result;
}
+ static MacroAssemblerCodePtr createLLIntCodePtr(void (*function)())
+ {
+ return createFromExecutableAddress(bitwise_cast<void*>(function));
+ }
explicit MacroAssemblerCodePtr(ReturnAddressPtr ra)
: m_value(ra.value())
{
@@ -340,6 +344,12 @@ public:
return MacroAssemblerCodeRef(codePtr);
}
+ // Helper for creating self-managed code refs from LLInt.
+ static MacroAssemblerCodeRef createLLIntCodeRef(void (*function)())
+ {
+ return createSelfManagedCodeRef(MacroAssemblerCodePtr::createFromExecutableAddress(bitwise_cast<void*>(function)));
+ }
+
ExecutableMemoryHandle* executableMemory() const
{
return m_executableMemory.get();
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h b/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
index f1aa6d4ad..910bc5a47 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
@@ -132,6 +132,11 @@ public:
}
}
+ void add32(RegisterID src, TrustedImm32 imm, RegisterID dest)
+ {
+ add32(imm, src, dest);
+ }
+
void add32(TrustedImm32 imm, Address address)
{
if (address.offset >= -32768 && address.offset <= 32767
@@ -291,11 +296,6 @@ public:
m_assembler.subu(srcDest, MIPSRegisters::zero, srcDest);
}
- void not32(RegisterID srcDest)
- {
- m_assembler.nor(srcDest, srcDest, MIPSRegisters::zero);
- }
-
void or32(RegisterID src, RegisterID dest)
{
m_assembler.orInsn(dest, dest, src);
@@ -373,6 +373,24 @@ public:
}
}
+ void sub32(RegisterID src, TrustedImm32 imm, RegisterID dest)
+ {
+ if (!imm.m_isPointer && imm.m_value >= -32767 && imm.m_value <= 32768
+ && !m_fixedWidth) {
+ /*
+ addiu dest, src, imm
+ */
+ m_assembler.addiu(dest, src, -imm.m_value);
+ } else {
+ /*
+ li immTemp, imm
+ subu dest, src, immTemp
+ */
+ move(imm, immTempRegister);
+ m_assembler.subu(dest, src, immTempRegister);
+ }
+ }
+
void sub32(TrustedImm32 imm, Address address)
{
if (address.offset >= -32768 && address.offset <= 32767
@@ -458,6 +476,11 @@ public:
void xor32(TrustedImm32 imm, RegisterID dest)
{
+ if (imm.m_value == -1) {
+ m_assembler.nor(dest, dest, MIPSRegisters::zero);
+ return;
+ }
+
/*
li immTemp, imm
xor dest, dest, immTemp
@@ -1203,6 +1226,13 @@ public:
return branchAdd32(cond, immTempRegister, dest);
}
+ Jump branchAdd32(ResultCondition cond, RegisterID src, TrustedImm32 imm, RegisterID dest)
+ {
+ move(imm, immTempRegister);
+ move(src, dest);
+ return branchAdd32(cond, immTempRegister, dest);
+ }
+
Jump branchMul32(ResultCondition cond, RegisterID src, RegisterID dest)
{
ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
@@ -1308,6 +1338,13 @@ public:
return branchSub32(cond, immTempRegister, dest);
}
+ Jump branchSub32(ResultCondition cond, RegisterID src, TrustedImm32 imm, RegisterID dest)
+ {
+ move(imm, immTempRegister);
+ move(src, dest);
+ return branchSub32(cond, immTempRegister, dest);
+ }
+
Jump branchOr32(ResultCondition cond, RegisterID src, RegisterID dest)
{
ASSERT((cond == Signed) || (cond == Zero) || (cond == NonZero));
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h b/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h
index a84f33748..2b5c0cc44 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h
@@ -209,11 +209,6 @@ public:
releaseScratch(scr);
}
- void not32(RegisterID src, RegisterID dest)
- {
- m_assembler.notlReg(src, dest);
- }
-
void or32(RegisterID src, RegisterID dest)
{
m_assembler.orlRegReg(src, dest);
@@ -380,6 +375,11 @@ public:
void xor32(TrustedImm32 imm, RegisterID srcDest)
{
+ if (imm.m_value == -1) {
+ m_assembler.notlReg(srcDest, srcDest);
+ return;
+ }
+
if ((srcDest != SH4Registers::r0) || (imm.m_value > 255) || (imm.m_value < 0)) {
RegisterID scr = claimScratch();
m_assembler.loadConstant((imm.m_value), scr);
@@ -1565,6 +1565,33 @@ public:
return branchAdd32(cond, scratchReg3, dest);
}
+ Jump branchAdd32(ResultCondition cond, RegisterID src, TrustedImm32 imm, RegisterID dest)
+ {
+ ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
+
+ if (src != dest)
+ move(src, dest);
+
+ if (cond == Overflow) {
+ move(imm, scratchReg3);
+ m_assembler.addvlRegReg(scratchReg3, dest);
+ return branchTrue();
+ }
+
+ add32(imm, dest);
+
+ if (cond == Signed) {
+ m_assembler.cmppz(dest);
+ return branchFalse();
+ }
+
+ compare32(0, dest, Equal);
+
+ if (cond == NotEqual)
+ return branchFalse();
+ return branchTrue();
+ }
+
Jump branchMul32(ResultCondition cond, RegisterID src, RegisterID dest)
{
ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
@@ -1642,6 +1669,14 @@ public:
return branchSub32(cond, scratchReg3, dest);
}
+ Jump branchSub32(ResultCondition cond, RegisterID src, TrustedImm32 imm, RegisterID dest)
+ {
+ move(imm, scratchReg3);
+ if (src != dest)
+ move(src, dest);
+ return branchSub32(cond, scratchReg3, dest);
+ }
+
Jump branchOr32(ResultCondition cond, RegisterID src, RegisterID dest)
{
ASSERT((cond == Signed) || (cond == Zero) || (cond == NonZero));
@@ -1681,11 +1716,6 @@ public:
m_assembler.neg(dst, dst);
}
- void not32(RegisterID dst)
- {
- m_assembler.notlReg(dst, dst);
- }
-
void urshift32(RegisterID shiftamount, RegisterID dest)
{
if (shiftamount == SH4Registers::r0)
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerX86.h b/Source/JavaScriptCore/assembler/MacroAssemblerX86.h
index cb2450f62..088fe196b 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerX86.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerX86.h
@@ -93,12 +93,6 @@ public:
m_assembler.addsd_mr(address.m_ptr, dest);
}
- void loadDouble(const void* address, FPRegisterID dest)
- {
- ASSERT(isSSE2Present());
- m_assembler.movsd_mr(address, dest);
- }
-
void storeDouble(FPRegisterID src, const void* address)
{
ASSERT(isSSE2Present());
@@ -110,14 +104,6 @@ public:
m_assembler.cvtsi2sd_mr(src.m_ptr, dest);
}
- void absDouble(FPRegisterID src, FPRegisterID dst)
- {
- ASSERT(src != dst);
- static const double negativeZeroConstant = -0.0;
- loadDouble(&negativeZeroConstant, dst);
- m_assembler.andnpd_rr(src, dst);
- }
-
void store32(TrustedImm32 imm, void* address)
{
m_assembler.movl_i32m(imm.m_value, address);
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h b/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h
index e6c39598b..8cb442cc5 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h
@@ -34,6 +34,11 @@
namespace JSC {
class MacroAssemblerX86Common : public AbstractMacroAssembler<X86Assembler> {
+protected:
+#if CPU(X86_64)
+ static const X86Registers::RegisterID scratchRegister = X86Registers::r11;
+#endif
+
static const int DoubleConditionBitInvert = 0x10;
static const int DoubleConditionBitSpecial = 0x20;
static const int DoubleConditionBits = DoubleConditionBitInvert | DoubleConditionBitSpecial;
@@ -86,6 +91,13 @@ public:
static const RegisterID stackPointerRegister = X86Registers::esp;
+#if ENABLE(JIT_CONSTANT_BLINDING)
+ static bool shouldBlindForSpecificArch(uint32_t value) { return value >= 0x00ffffff; }
+#if CPU(X86_64)
+ static bool shouldBlindForSpecificArch(uintptr_t value) { return value >= 0x00ffffff; }
+#endif
+#endif
+
// Integer arithmetic operations:
//
// Operations are typically two operand - operation(source, srcDst)
@@ -223,16 +235,6 @@ public:
m_assembler.negl_m(srcDest.offset, srcDest.base);
}
- void not32(RegisterID srcDest)
- {
- m_assembler.notl_r(srcDest);
- }
-
- void not32(Address srcDest)
- {
- m_assembler.notl_m(srcDest.offset, srcDest.base);
- }
-
void or32(RegisterID src, RegisterID dest)
{
m_assembler.orl_rr(src, dest);
@@ -375,7 +377,6 @@ public:
m_assembler.subl_rm(src, dest.offset, dest.base);
}
-
void xor32(RegisterID src, RegisterID dest)
{
m_assembler.xorl_rr(src, dest);
@@ -383,11 +384,17 @@ public:
void xor32(TrustedImm32 imm, Address dest)
{
- m_assembler.xorl_im(imm.m_value, dest.offset, dest.base);
+ if (imm.m_value == -1)
+ m_assembler.notl_m(dest.offset, dest.base);
+ else
+ m_assembler.xorl_im(imm.m_value, dest.offset, dest.base);
}
void xor32(TrustedImm32 imm, RegisterID dest)
{
+ if (imm.m_value == -1)
+ m_assembler.notl_r(dest);
+ else
m_assembler.xorl_ir(imm.m_value, dest);
}
@@ -424,6 +431,23 @@ public:
m_assembler.sqrtsd_rr(src, dst);
}
+ void absDouble(FPRegisterID src, FPRegisterID dst)
+ {
+ ASSERT(src != dst);
+ static const double negativeZeroConstant = -0.0;
+ loadDouble(&negativeZeroConstant, dst);
+ m_assembler.andnpd_rr(src, dst);
+ }
+
+ void negateDouble(FPRegisterID src, FPRegisterID dst)
+ {
+ ASSERT(src != dst);
+ static const double negativeZeroConstant = -0.0;
+ loadDouble(&negativeZeroConstant, dst);
+ m_assembler.xorpd_rr(src, dst);
+ }
+
+
// Memory access operations:
//
// Loads are of the form load(address, destination) and stores of the form
@@ -620,6 +644,17 @@ public:
m_assembler.movsd_rr(src, dest);
}
+ void loadDouble(const void* address, FPRegisterID dest)
+ {
+#if CPU(X86)
+ ASSERT(isSSE2Present());
+ m_assembler.movsd_mr(address, dest);
+#else
+ move(TrustedImmPtr(address), scratchRegister);
+ loadDouble(scratchRegister, dest);
+#endif
+ }
+
void loadDouble(ImplicitAddress address, FPRegisterID dest)
{
ASSERT(isSSE2Present());
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h b/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h
index 846049999..a2b4311e5 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h
@@ -35,9 +35,6 @@
namespace JSC {
class MacroAssemblerX86_64 : public MacroAssemblerX86Common {
-protected:
- static const X86Registers::RegisterID scratchRegister = X86Registers::r11;
-
public:
static const Scale ScalePtr = TimesEight;
@@ -88,12 +85,6 @@ public:
}
}
- void loadDouble(const void* address, FPRegisterID dest)
- {
- move(TrustedImmPtr(address), scratchRegister);
- loadDouble(scratchRegister, dest);
- }
-
void addDouble(AbsoluteAddress address, FPRegisterID dest)
{
move(TrustedImmPtr(address.m_ptr), scratchRegister);
@@ -106,14 +97,6 @@ public:
m_assembler.cvtsi2sd_rr(scratchRegister, dest);
}
- void absDouble(FPRegisterID src, FPRegisterID dst)
- {
- ASSERT(src != dst);
- static const double negativeZeroConstant = -0.0;
- loadDouble(&negativeZeroConstant, dst);
- m_assembler.andnpd_rr(src, dst);
- }
-
void store32(TrustedImm32 imm, void* address)
{
move(TrustedImmPtr(address), scratchRegister);
@@ -233,6 +216,11 @@ public:
move(src, dest);
orPtr(imm, dest);
}
+
+ void rotateRightPtr(TrustedImm32 imm, RegisterID srcDst)
+ {
+ m_assembler.rorq_i8r(imm.m_value, srcDst);
+ }
void subPtr(RegisterID src, RegisterID dest)
{
@@ -254,13 +242,17 @@ public:
{
m_assembler.xorq_rr(src, dest);
}
+
+ void xorPtr(RegisterID src, Address dest)
+ {
+ m_assembler.xorq_rm(src, dest.offset, dest.base);
+ }
void xorPtr(TrustedImm32 imm, RegisterID srcDest)
{
m_assembler.xorq_ir(imm.m_value, srcDest);
}
-
void loadPtr(ImplicitAddress address, RegisterID dest)
{
m_assembler.movq_mr(address.offset, address.base, dest);
@@ -351,6 +343,13 @@ public:
m_assembler.movzbl_rr(dest, dest);
}
+ void comparePtr(RelationalCondition cond, RegisterID left, RegisterID right, RegisterID dest)
+ {
+ m_assembler.cmpq_rr(right, left);
+ m_assembler.setCC_r(x86Condition(cond), dest);
+ m_assembler.movzbl_rr(dest, dest);
+ }
+
Jump branchAdd32(ResultCondition cond, TrustedImm32 src, AbsoluteAddress dest)
{
move(TrustedImmPtr(dest.m_ptr), scratchRegister);
@@ -459,6 +458,12 @@ public:
return Jump(m_assembler.jCC(x86Condition(cond)));
}
+ Jump branchSubPtr(ResultCondition cond, RegisterID src1, TrustedImm32 src2, RegisterID dest)
+ {
+ move(src1, dest);
+ return branchSubPtr(cond, src2, dest);
+ }
+
DataLabelPtr moveWithPatch(TrustedImmPtr initialValue, RegisterID dest)
{
m_assembler.movq_i64r(initialValue.asIntptr(), dest);
@@ -503,6 +508,8 @@ public:
return FunctionPtr(X86Assembler::readPointer(call.dataLabelPtrAtOffset(-REPTACH_OFFSET_CALL_R11).dataLocation()));
}
+ static RegisterID scratchRegisterForBlinding() { return scratchRegister; }
+
private:
friend class LinkBuffer;
friend class RepatchBuffer;
diff --git a/Source/JavaScriptCore/assembler/SH4Assembler.h b/Source/JavaScriptCore/assembler/SH4Assembler.h
index 280a5de85..1cf96b735 100644
--- a/Source/JavaScriptCore/assembler/SH4Assembler.h
+++ b/Source/JavaScriptCore/assembler/SH4Assembler.h
@@ -31,6 +31,7 @@
#include "AssemblerBuffer.h"
#include "AssemblerBufferWithConstantPool.h"
+#include "JITCompilationEffort.h"
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
@@ -1514,9 +1515,9 @@ public:
return reinterpret_cast<void*>(readPCrelativeAddress((*instructionPtr & 0xff), instructionPtr));
}
- PassRefPtr<ExecutableMemoryHandle> executableCopy(JSGlobalData& globalData, void* ownerUID)
+ PassRefPtr<ExecutableMemoryHandle> executableCopy(JSGlobalData& globalData, void* ownerUID, JITCompilationEffort effort)
{
- return m_buffer.executableCopy(globalData, ownerUID);
+ return m_buffer.executableCopy(globalData, ownerUID, effort);
}
void prefix(uint16_t pre)
diff --git a/Source/JavaScriptCore/assembler/X86Assembler.h b/Source/JavaScriptCore/assembler/X86Assembler.h
index 25f8602e8..b24fffb8f 100644
--- a/Source/JavaScriptCore/assembler/X86Assembler.h
+++ b/Source/JavaScriptCore/assembler/X86Assembler.h
@@ -29,6 +29,7 @@
#if ENABLE(ASSEMBLER) && (CPU(X86) || CPU(X86_64))
#include "AssemblerBuffer.h"
+#include "JITCompilationEffort.h"
#include <stdint.h>
#include <wtf/Assertions.h>
#include <wtf/Vector.h>
@@ -215,7 +216,12 @@ private:
GROUP1_OP_CMP = 7,
GROUP1A_OP_POP = 0,
-
+
+ GROUP2_OP_ROL = 0,
+ GROUP2_OP_ROR = 1,
+ GROUP2_OP_RCL = 2,
+ GROUP2_OP_RCR = 3,
+
GROUP2_OP_SHL = 4,
GROUP2_OP_SHR = 5,
GROUP2_OP_SAR = 7,
@@ -635,6 +641,22 @@ public:
m_formatter.immediate32(imm);
}
}
+
+ void xorq_rm(RegisterID src, int offset, RegisterID base)
+ {
+ m_formatter.oneByteOp64(OP_XOR_EvGv, src, base, offset);
+ }
+
+ void rorq_i8r(int imm, RegisterID dst)
+ {
+ if (imm == 1)
+ m_formatter.oneByteOp64(OP_GROUP2_Ev1, GROUP2_OP_ROR, dst);
+ else {
+ m_formatter.oneByteOp64(OP_GROUP2_EvIb, GROUP2_OP_ROR, dst);
+ m_formatter.immediate8(imm);
+ }
+ }
+
#endif
void sarl_i8r(int imm, RegisterID dst)
@@ -1782,9 +1804,9 @@ public:
return b.m_offset - a.m_offset;
}
- PassRefPtr<ExecutableMemoryHandle> executableCopy(JSGlobalData& globalData, void* ownerUID)
+ PassRefPtr<ExecutableMemoryHandle> executableCopy(JSGlobalData& globalData, void* ownerUID, JITCompilationEffort effort)
{
- return m_formatter.executableCopy(globalData, ownerUID);
+ return m_formatter.executableCopy(globalData, ownerUID, effort);
}
unsigned debugOffset() { return m_formatter.debugOffset(); }
@@ -2130,9 +2152,9 @@ private:
bool isAligned(int alignment) const { return m_buffer.isAligned(alignment); }
void* data() const { return m_buffer.data(); }
- PassRefPtr<ExecutableMemoryHandle> executableCopy(JSGlobalData& globalData, void* ownerUID)
+ PassRefPtr<ExecutableMemoryHandle> executableCopy(JSGlobalData& globalData, void* ownerUID, JITCompilationEffort effort)
{
- return m_buffer.executableCopy(globalData, ownerUID);
+ return m_buffer.executableCopy(globalData, ownerUID, effort);
}
unsigned debugOffset() { return m_buffer.debugOffset(); }
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
index ab89ad965..20972cc63 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
@@ -226,7 +226,7 @@ static bool isPropertyAccess(OpcodeID opcodeID)
}
}
-static unsigned instructionOffsetForNth(ExecState* exec, const Vector<Instruction>& instructions, int nth, bool (*predicate)(OpcodeID))
+static unsigned instructionOffsetForNth(ExecState* exec, const RefCountedArray<Instruction>& instructions, int nth, bool (*predicate)(OpcodeID))
{
size_t i = 0;
while (i < instructions.size()) {
@@ -347,18 +347,13 @@ void CodeBlock::printStructures(const Instruction* vPC) const
void CodeBlock::dump(ExecState* exec) const
{
- if (!m_instructions) {
- dataLog("No instructions available.\n");
- return;
- }
-
size_t instructionCount = 0;
for (size_t i = 0; i < instructions().size(); i += opcodeLengths[exec->interpreter()->getOpcodeID(instructions()[i].u.opcode)])
++instructionCount;
dataLog("%lu m_instructions; %lu bytes at %p; %d parameter(s); %d callee register(s); %d variable(s)\n\n",
- static_cast<unsigned long>(instructionCount),
+ static_cast<unsigned long>(instructions().size()),
static_cast<unsigned long>(instructions().size() * sizeof(Instruction)),
this, m_numParameters, m_numCalleeRegisters, m_numVars);
@@ -689,10 +684,6 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
++it;
break;
}
- case op_bitnot: {
- printUnaryOp(exec, location, it, "bitnot");
- break;
- }
case op_check_has_instance: {
int base = (++it)->u.operand;
dataLog("[%4d] check_has_instance\t\t %s\n", location, registerName(exec, base).data());
@@ -1424,11 +1415,9 @@ CodeBlock::CodeBlock(CopyParsedBlockTag, CodeBlock& other, SymbolTable* symTab)
, m_numVars(other.m_numVars)
, m_numCapturedVars(other.m_numCapturedVars)
, m_isConstructor(other.m_isConstructor)
- , m_shouldDiscardBytecode(false)
, m_ownerExecutable(*other.m_globalData, other.m_ownerExecutable.get(), other.m_ownerExecutable.get())
, m_globalData(other.m_globalData)
, m_instructions(other.m_instructions)
- , m_instructionCount(other.m_instructionCount)
, m_thisRegister(other.m_thisRegister)
, m_argumentsRegister(other.m_argumentsRegister)
, m_activationRegister(other.m_activationRegister)
@@ -1484,12 +1473,9 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, JSGlo
, m_numCalleeRegisters(0)
, m_numVars(0)
, m_isConstructor(isConstructor)
- , m_shouldDiscardBytecode(false)
, m_numParameters(0)
, m_ownerExecutable(globalObject->globalData(), ownerExecutable, ownerExecutable)
, m_globalData(0)
- , m_instructions(adoptRef(new Instructions))
- , m_instructionCount(0)
, m_argumentsRegister(-1)
, m_needsFullScopeChain(ownerExecutable->needsActivation())
, m_usesEval(ownerExecutable->usesEval())
@@ -1595,13 +1581,15 @@ void CodeBlock::visitStructures(SlotVisitor& visitor, Instruction* vPC) const
}
if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_chain) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_getter_chain) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_custom_chain)) {
visitor.append(&vPC[4].u.structure);
- visitor.append(&vPC[5].u.structureChain);
+ if (vPC[5].u.structureChain)
+ visitor.append(&vPC[5].u.structureChain);
return;
}
if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_transition)) {
visitor.append(&vPC[4].u.structure);
visitor.append(&vPC[5].u.structure);
- visitor.append(&vPC[6].u.structureChain);
+ if (vPC[6].u.structureChain)
+ visitor.append(&vPC[6].u.structureChain);
return;
}
if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id) && vPC[4].u.structure) {
@@ -1631,6 +1619,32 @@ void EvalCodeCache::visitAggregate(SlotVisitor& visitor)
void CodeBlock::visitAggregate(SlotVisitor& visitor)
{
+#if ENABLE(PARALLEL_GC) && ENABLE(DFG_JIT)
+ if (!!m_dfgData) {
+ // 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_dfgData->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_dfgData->visitAggregateHasBeenCalled, 0, 1));
+ }
+#endif // ENABLE(PARALLEL_GC) && ENABLE(DFG_JIT)
+
if (!!m_alternative)
m_alternative->visitAggregate(visitor);
@@ -1903,12 +1917,6 @@ void CodeBlock::finalizeUnconditionally()
}
}
#endif
-
- // Handle the bytecode discarding chore.
- if (m_shouldDiscardBytecode) {
- discardBytecode();
- m_shouldDiscardBytecode = false;
- }
}
void CodeBlock::stronglyVisitStrongReferences(SlotVisitor& visitor)
@@ -1980,7 +1988,7 @@ void CodeBlock::stronglyVisitWeakReferences(SlotVisitor& visitor)
HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset)
{
- ASSERT(bytecodeOffset < m_instructionCount);
+ ASSERT(bytecodeOffset < instructions().size());
if (!m_rareData)
return 0;
@@ -1998,7 +2006,7 @@ HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset)
int CodeBlock::lineNumberForBytecodeOffset(unsigned bytecodeOffset)
{
- ASSERT(bytecodeOffset < m_instructionCount);
+ ASSERT(bytecodeOffset < instructions().size());
if (!m_rareData)
return m_ownerExecutable->source().firstLine();
@@ -2022,7 +2030,7 @@ int CodeBlock::lineNumberForBytecodeOffset(unsigned bytecodeOffset)
void CodeBlock::expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& divot, int& startOffset, int& endOffset)
{
- ASSERT(bytecodeOffset < m_instructionCount);
+ ASSERT(bytecodeOffset < instructions().size());
if (!m_rareData) {
startOffset = 0;
@@ -2102,8 +2110,6 @@ bool CodeBlock::hasGlobalResolveInfoAtBytecodeOffset(unsigned bytecodeOffset)
void CodeBlock::shrinkToFit()
{
- instructions().shrinkToFit();
-
#if ENABLE(CLASSIC_INTERPRETER)
m_propertyAccessInstructions.shrinkToFit();
m_globalResolveInstructions.shrinkToFit();
@@ -2345,21 +2351,21 @@ void FunctionCodeBlock::jettison()
static_cast<FunctionExecutable*>(ownerExecutable())->jettisonOptimizedCodeFor(*globalData(), m_isConstructor ? CodeForConstruct : CodeForCall);
}
-void ProgramCodeBlock::jitCompileImpl(JSGlobalData& globalData)
+bool ProgramCodeBlock::jitCompileImpl(JSGlobalData& globalData)
{
ASSERT(getJITType() == JITCode::InterpreterThunk);
ASSERT(this == replacement());
return static_cast<ProgramExecutable*>(ownerExecutable())->jitCompile(globalData);
}
-void EvalCodeBlock::jitCompileImpl(JSGlobalData& globalData)
+bool EvalCodeBlock::jitCompileImpl(JSGlobalData& globalData)
{
ASSERT(getJITType() == JITCode::InterpreterThunk);
ASSERT(this == replacement());
return static_cast<EvalExecutable*>(ownerExecutable())->jitCompile(globalData);
}
-void FunctionCodeBlock::jitCompileImpl(JSGlobalData& globalData)
+bool FunctionCodeBlock::jitCompileImpl(JSGlobalData& globalData)
{
ASSERT(getJITType() == JITCode::InterpreterThunk);
ASSERT(this == replacement());
@@ -2467,7 +2473,38 @@ void CodeBlock::dumpValueProfiles()
}
#endif
-#ifndef NDEBUG
+size_t CodeBlock::predictedMachineCodeSize()
+{
+ // This will be called from CodeBlock::CodeBlock before either m_globalData or the
+ // instructions have been initialized. It's OK to return 0 because what will really
+ // matter is the recomputation of this value when the slow path is triggered.
+ if (!m_globalData)
+ return 0;
+
+ if (!m_globalData->machineCodeBytesPerBytecodeWordForBaselineJIT)
+ return 0; // It's as good of a prediction as we'll get.
+
+ // Be conservative: return a size that will be an overestimation 84% of the time.
+ double multiplier = m_globalData->machineCodeBytesPerBytecodeWordForBaselineJIT.mean() +
+ m_globalData->machineCodeBytesPerBytecodeWordForBaselineJIT.standardDeviation();
+
+ // Be paranoid: silently reject bogus multipiers. Silently doing the "wrong" thing
+ // here is OK, since this whole method is just a heuristic.
+ if (multiplier < 0 || multiplier > 1000)
+ return 0;
+
+ double doubleResult = multiplier * m_instructions.size();
+
+ // Be even more paranoid: silently reject values that won't fit into a size_t. If
+ // the function is so huge that we can't even fit it into virtual memory then we
+ // should probably have some other guards in place to prevent us from even getting
+ // to this point.
+ if (doubleResult > std::numeric_limits<size_t>::max())
+ return 0;
+
+ return static_cast<size_t>(doubleResult);
+}
+
bool CodeBlock::usesOpcode(OpcodeID opcodeID)
{
Interpreter* interpreter = globalData()->interpreter;
@@ -2492,6 +2529,5 @@ bool CodeBlock::usesOpcode(OpcodeID opcodeID)
return false;
}
-#endif
} // namespace JSC
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.h b/Source/JavaScriptCore/bytecode/CodeBlock.h
index 195aa62ca..469028097 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.h
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.h
@@ -41,6 +41,7 @@
#include "DFGOSREntry.h"
#include "DFGOSRExit.h"
#include "EvalCodeCache.h"
+#include "ExecutionCounter.h"
#include "ExpressionRangeInfo.h"
#include "GlobalResolveInfo.h"
#include "HandlerInfo.h"
@@ -61,6 +62,7 @@
#include "UString.h"
#include "UnconditionalFinalizer.h"
#include "ValueProfile.h"
+#include <wtf/RefCountedArray.h>
#include <wtf/FastAllocBase.h>
#include <wtf/PassOwnPtr.h>
#include <wtf/RefPtr.h>
@@ -127,8 +129,6 @@ namespace JSC {
}
#endif
- bool canProduceCopyWithBytecode() { return hasInstructions(); }
-
void visitAggregate(SlotVisitor&);
static void dumpStatistics();
@@ -341,20 +341,15 @@ namespace JSC {
void setIsNumericCompareFunction(bool isNumericCompareFunction) { m_isNumericCompareFunction = isNumericCompareFunction; }
bool isNumericCompareFunction() { return m_isNumericCompareFunction; }
- bool hasInstructions() const { return !!m_instructions; }
- unsigned numberOfInstructions() const { return !m_instructions ? 0 : m_instructions->m_instructions.size(); }
- Vector<Instruction>& instructions() { return m_instructions->m_instructions; }
- const Vector<Instruction>& instructions() const { return m_instructions->m_instructions; }
- void discardBytecode() { m_instructions.clear(); }
- void discardBytecodeLater()
- {
- m_shouldDiscardBytecode = true;
- }
+ unsigned numberOfInstructions() const { return m_instructions.size(); }
+ RefCountedArray<Instruction>& instructions() { return m_instructions; }
+ const RefCountedArray<Instruction>& instructions() const { return m_instructions; }
+
+ size_t predictedMachineCodeSize();
bool usesOpcode(OpcodeID);
- unsigned instructionCount() { return m_instructionCount; }
- void setInstructionCount(unsigned instructionCount) { m_instructionCount = instructionCount; }
+ unsigned instructionCount() { return m_instructions.size(); }
#if ENABLE(JIT)
void setJITCode(const JITCode& code, MacroAssemblerCodePtr codeWithArityCheck)
@@ -374,18 +369,20 @@ namespace JSC {
ExecutableMemoryHandle* executableMemory() { return getJITCode().getExecutableMemory(); }
virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*) = 0;
virtual void jettison() = 0;
- bool jitCompile(JSGlobalData& globalData)
+ enum JITCompilationResult { AlreadyCompiled, CouldNotCompile, CompiledSuccessfully };
+ JITCompilationResult jitCompile(JSGlobalData& globalData)
{
if (getJITType() != JITCode::InterpreterThunk) {
ASSERT(getJITType() == JITCode::BaselineJIT);
- return false;
+ return AlreadyCompiled;
}
#if ENABLE(JIT)
- jitCompileImpl(globalData);
- return true;
+ if (jitCompileImpl(globalData))
+ return CompiledSuccessfully;
+ return CouldNotCompile;
#else
UNUSED_PARAM(globalData);
- return false;
+ return CouldNotCompile;
#endif
}
virtual CodeBlock* replacement() = 0;
@@ -541,11 +538,10 @@ namespace JSC {
{
ValueProfile* result = WTF::genericBinarySearch<ValueProfile, int, getValueProfileBytecodeOffset>(m_valueProfiles, m_valueProfiles.size(), bytecodeOffset);
ASSERT(result->m_bytecodeOffset != -1);
- ASSERT(!hasInstructions()
- || instructions()[bytecodeOffset + opcodeLength(
- m_globalData->interpreter->getOpcodeID(
- instructions()[
- bytecodeOffset].u.opcode)) - 1].u.profile == result);
+ ASSERT(instructions()[bytecodeOffset + opcodeLength(
+ m_globalData->interpreter->getOpcodeID(
+ instructions()[
+ bytecodeOffset].u.opcode)) - 1].u.profile == result);
return result;
}
PredictedType valueProfilePredictionForBytecodeOffset(int bytecodeOffset)
@@ -839,24 +835,29 @@ namespace JSC {
// Functions for controlling when JITting kicks in, in a mixed mode
// execution world.
+ bool checkIfJITThresholdReached()
+ {
+ return m_llintExecuteCounter.checkIfThresholdCrossedAndSet(this);
+ }
+
void dontJITAnytimeSoon()
{
- m_llintExecuteCounter = Options::executionCounterValueForDontJITAnytimeSoon;
+ m_llintExecuteCounter.deferIndefinitely();
}
void jitAfterWarmUp()
{
- m_llintExecuteCounter = Options::executionCounterValueForJITAfterWarmUp;
+ m_llintExecuteCounter.setNewThreshold(Options::thresholdForJITAfterWarmUp, this);
}
void jitSoon()
{
- m_llintExecuteCounter = Options::executionCounterValueForJITSoon;
+ m_llintExecuteCounter.setNewThreshold(Options::thresholdForJITSoon, this);
}
int32_t llintExecuteCounter() const
{
- return m_llintExecuteCounter;
+ return m_llintExecuteCounter.m_counter;
}
// Functions for controlling when tiered compilation kicks in. This
@@ -895,31 +896,41 @@ namespace JSC {
int32_t counterValueForOptimizeAfterWarmUp()
{
- return Options::executionCounterValueForOptimizeAfterWarmUp << reoptimizationRetryCounter();
+ return Options::thresholdForOptimizeAfterWarmUp << reoptimizationRetryCounter();
}
int32_t counterValueForOptimizeAfterLongWarmUp()
{
- return Options::executionCounterValueForOptimizeAfterLongWarmUp << reoptimizationRetryCounter();
+ return Options::thresholdForOptimizeAfterLongWarmUp << reoptimizationRetryCounter();
}
int32_t* addressOfJITExecuteCounter()
{
- return &m_jitExecuteCounter;
+ return &m_jitExecuteCounter.m_counter;
}
- static ptrdiff_t offsetOfJITExecuteCounter() { return OBJECT_OFFSETOF(CodeBlock, m_jitExecuteCounter); }
+ static ptrdiff_t offsetOfJITExecuteCounter() { return OBJECT_OFFSETOF(CodeBlock, m_jitExecuteCounter) + OBJECT_OFFSETOF(ExecutionCounter, m_counter); }
+ static ptrdiff_t offsetOfJITExecutionActiveThreshold() { return OBJECT_OFFSETOF(CodeBlock, m_jitExecuteCounter) + OBJECT_OFFSETOF(ExecutionCounter, m_activeThreshold); }
+ static ptrdiff_t offsetOfJITExecutionTotalCount() { return OBJECT_OFFSETOF(CodeBlock, m_jitExecuteCounter) + OBJECT_OFFSETOF(ExecutionCounter, m_totalCount); }
- int32_t jitExecuteCounter() const { return m_jitExecuteCounter; }
+ int32_t jitExecuteCounter() const { return m_jitExecuteCounter.m_counter; }
unsigned optimizationDelayCounter() const { return m_optimizationDelayCounter; }
+ // Check if the optimization threshold has been reached, and if not,
+ // adjust the heuristics accordingly. Returns true if the threshold has
+ // been reached.
+ bool checkIfOptimizationThresholdReached()
+ {
+ return m_jitExecuteCounter.checkIfThresholdCrossedAndSet(this);
+ }
+
// Call this to force the next optimization trigger to fire. This is
// rarely wise, since optimization triggers are typically more
// expensive than executing baseline code.
void optimizeNextInvocation()
{
- m_jitExecuteCounter = Options::executionCounterValueForOptimizeNextInvocation;
+ m_jitExecuteCounter.setNewThreshold(0, this);
}
// Call this to prevent optimization from happening again. Note that
@@ -929,7 +940,7 @@ namespace JSC {
// the future as well.
void dontOptimizeAnytimeSoon()
{
- m_jitExecuteCounter = Options::executionCounterValueForDontOptimizeAnytimeSoon;
+ m_jitExecuteCounter.deferIndefinitely();
}
// Call this to reinitialize the counter to its starting state,
@@ -940,14 +951,14 @@ namespace JSC {
// counter that this corresponds to is also available directly.
void optimizeAfterWarmUp()
{
- m_jitExecuteCounter = counterValueForOptimizeAfterWarmUp();
+ m_jitExecuteCounter.setNewThreshold(counterValueForOptimizeAfterWarmUp(), this);
}
// Call this to force an optimization trigger to fire only after
// a lot of warm-up.
void optimizeAfterLongWarmUp()
{
- m_jitExecuteCounter = counterValueForOptimizeAfterLongWarmUp();
+ m_jitExecuteCounter.setNewThreshold(counterValueForOptimizeAfterLongWarmUp(), this);
}
// Call this to cause an optimization trigger to fire soon, but
@@ -970,7 +981,7 @@ namespace JSC {
// in the baseline code.
void optimizeSoon()
{
- m_jitExecuteCounter = Options::executionCounterValueForOptimizeSoon << reoptimizationRetryCounter();
+ m_jitExecuteCounter.setNewThreshold(Options::thresholdForOptimizeSoon << reoptimizationRetryCounter(), this);
}
// The speculative JIT tracks its success rate, so that we can
@@ -1047,12 +1058,9 @@ namespace JSC {
int m_numCapturedVars;
bool m_isConstructor;
- // This is public because otherwise we would have many friends.
- bool m_shouldDiscardBytecode;
-
protected:
#if ENABLE(JIT)
- virtual void jitCompileImpl(JSGlobalData&) = 0;
+ virtual bool jitCompileImpl(JSGlobalData&) = 0;
#endif
virtual void visitWeakReferences(SlotVisitor&);
virtual void finalizeUnconditionally();
@@ -1115,11 +1123,7 @@ namespace JSC {
WriteBarrier<ScriptExecutable> m_ownerExecutable;
JSGlobalData* m_globalData;
- struct Instructions : public RefCounted<Instructions> {
- Vector<Instruction> m_instructions;
- };
- RefPtr<Instructions> m_instructions;
- unsigned m_instructionCount;
+ RefCountedArray<Instruction> m_instructions;
int m_thisRegister;
int m_argumentsRegister;
@@ -1186,6 +1190,7 @@ namespace JSC {
bool isJettisoned;
bool livenessHasBeenProved; // Initialized and used on every GC.
bool allTransitionsHaveBeenMarked; // Initialized and used on every GC.
+ unsigned visitAggregateHasBeenCalled; // Unsigned to make it work seamlessly with the broadest set of CAS implementations.
};
OwnPtr<DFGData> m_dfgData;
@@ -1217,13 +1222,14 @@ namespace JSC {
OwnPtr<CodeBlock> m_alternative;
- int32_t m_llintExecuteCounter;
+ ExecutionCounter m_llintExecuteCounter;
- int32_t m_jitExecuteCounter;
+ ExecutionCounter m_jitExecuteCounter;
+ int32_t m_totalJITExecutions;
uint32_t m_speculativeSuccessCounter;
uint32_t m_speculativeFailCounter;
- uint8_t m_optimizationDelayCounter;
- uint8_t m_reoptimizationRetryCounter;
+ uint16_t m_optimizationDelayCounter;
+ uint16_t m_reoptimizationRetryCounter;
struct RareData {
WTF_MAKE_FAST_ALLOCATED;
@@ -1300,7 +1306,7 @@ namespace JSC {
protected:
virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*);
virtual void jettison();
- virtual void jitCompileImpl(JSGlobalData&);
+ virtual bool jitCompileImpl(JSGlobalData&);
virtual CodeBlock* replacement();
virtual bool canCompileWithDFGInternal();
#endif
@@ -1335,7 +1341,7 @@ namespace JSC {
protected:
virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*);
virtual void jettison();
- virtual void jitCompileImpl(JSGlobalData&);
+ virtual bool jitCompileImpl(JSGlobalData&);
virtual CodeBlock* replacement();
virtual bool canCompileWithDFGInternal();
#endif
@@ -1373,33 +1379,12 @@ namespace JSC {
protected:
virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*);
virtual void jettison();
- virtual void jitCompileImpl(JSGlobalData&);
+ virtual bool jitCompileImpl(JSGlobalData&);
virtual CodeBlock* replacement();
virtual bool canCompileWithDFGInternal();
#endif
};
- // Use this if you want to copy a code block and you're paranoid about a GC
- // happening.
- class BytecodeDestructionBlocker {
- public:
- BytecodeDestructionBlocker(CodeBlock* codeBlock)
- : m_codeBlock(codeBlock)
- , m_oldValueOfShouldDiscardBytecode(codeBlock->m_shouldDiscardBytecode)
- {
- codeBlock->m_shouldDiscardBytecode = false;
- }
-
- ~BytecodeDestructionBlocker()
- {
- m_codeBlock->m_shouldDiscardBytecode = m_oldValueOfShouldDiscardBytecode;
- }
-
- private:
- CodeBlock* m_codeBlock;
- bool m_oldValueOfShouldDiscardBytecode;
- };
-
inline CodeBlock* baselineCodeBlockForOriginAndBaselineCodeBlock(const CodeOrigin& codeOrigin, CodeBlock* baselineCodeBlock)
{
if (codeOrigin.inlineCallFrame) {
diff --git a/Source/JavaScriptCore/bytecode/CodeType.h b/Source/JavaScriptCore/bytecode/CodeType.h
index 03485e564..d33677ae7 100644
--- a/Source/JavaScriptCore/bytecode/CodeType.h
+++ b/Source/JavaScriptCore/bytecode/CodeType.h
@@ -26,11 +26,28 @@
#ifndef CodeType_h
#define CodeType_h
+#include <wtf/Platform.h>
+
namespace JSC {
enum CodeType { GlobalCode, EvalCode, FunctionCode };
+inline const char* codeTypeToString(CodeType codeType)
+{
+ switch (codeType) {
+ case GlobalCode:
+ return "GlobalCode";
+ case EvalCode:
+ return "EvalCode";
+ case FunctionCode:
+ return "FunctionCode";
+ default:
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
}
+} // namespace JSC
+
#endif // CodeType_h
diff --git a/Source/JavaScriptCore/bytecode/ExecutionCounter.cpp b/Source/JavaScriptCore/bytecode/ExecutionCounter.cpp
new file mode 100644
index 000000000..b3fd3ef26
--- /dev/null
+++ b/Source/JavaScriptCore/bytecode/ExecutionCounter.cpp
@@ -0,0 +1,165 @@
+/*
+ * 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 "ExecutionCounter.h"
+
+#include "CodeBlock.h"
+#include "ExecutableAllocator.h"
+#include <wtf/DataLog.h>
+
+namespace JSC {
+
+ExecutionCounter::ExecutionCounter()
+{
+ reset();
+}
+
+bool ExecutionCounter::checkIfThresholdCrossedAndSet(CodeBlock* codeBlock)
+{
+ if (hasCrossedThreshold(codeBlock))
+ return true;
+
+ if (setThreshold(codeBlock))
+ return true;
+
+ return false;
+}
+
+void ExecutionCounter::setNewThreshold(int32_t threshold, CodeBlock* codeBlock)
+{
+ reset();
+ m_activeThreshold = threshold;
+ setThreshold(codeBlock);
+}
+
+void ExecutionCounter::deferIndefinitely()
+{
+ m_totalCount = 0;
+ m_activeThreshold = std::numeric_limits<int32_t>::max();
+ m_counter = std::numeric_limits<int32_t>::min();
+}
+
+double ExecutionCounter::applyMemoryUsageHeuristics(int32_t value, CodeBlock* codeBlock)
+{
+#if ENABLE(JIT)
+ double multiplier =
+ ExecutableAllocator::memoryPressureMultiplier(
+ codeBlock->predictedMachineCodeSize());
+#else
+ // This code path will probably not be taken, but if it is, we fake it.
+ double multiplier = 1.0;
+ UNUSED_PARAM(codeBlock);
+#endif
+ ASSERT(multiplier >= 1.0);
+ return multiplier * value;
+}
+
+int32_t ExecutionCounter::applyMemoryUsageHeuristicsAndConvertToInt(
+ int32_t value, CodeBlock* codeBlock)
+{
+ double doubleResult = applyMemoryUsageHeuristics(value, codeBlock);
+
+ ASSERT(doubleResult >= 0);
+
+ if (doubleResult > std::numeric_limits<int32_t>::max())
+ return std::numeric_limits<int32_t>::max();
+
+ return static_cast<int32_t>(doubleResult);
+}
+
+bool ExecutionCounter::hasCrossedThreshold(CodeBlock* codeBlock) const
+{
+ // This checks if the current count rounded up to the threshold we were targeting.
+ // For example, if we are using half of available executable memory and have
+ // m_activeThreshold = 1000, applyMemoryUsageHeuristics(m_activeThreshold) will be
+ // 2000, but we will pretend as if the threshold was crossed if we reach 2000 -
+ // 1000 / 2, or 1500. The reasoning here is that we want to avoid thrashing. If
+ // this method returns false, then the JIT's threshold for when it will again call
+ // into the slow path (which will call this method a second time) will be set
+ // according to the difference between the current count and the target count
+ // according to *current* memory usage. But by the time we call into this again, we
+ // may have JIT'ed more code, and so the target count will increase slightly. This
+ // may lead to a repeating pattern where the target count is slightly incremented,
+ // the JIT immediately matches that increase, calls into the slow path again, and
+ // again the target count is slightly incremented. Instead of having this vicious
+ // cycle, we declare victory a bit early if the difference between the current
+ // total and our target according to memory heuristics is small. Our definition of
+ // small is arbitrarily picked to be half of the original threshold (i.e.
+ // m_activeThreshold).
+
+ double modifiedThreshold = applyMemoryUsageHeuristics(m_activeThreshold, codeBlock);
+
+ return static_cast<double>(m_totalCount) + m_counter >=
+ modifiedThreshold - static_cast<double>(m_activeThreshold) / 2;
+}
+
+bool ExecutionCounter::setThreshold(CodeBlock* codeBlock)
+{
+ if (m_activeThreshold == std::numeric_limits<int32_t>::max()) {
+ deferIndefinitely();
+ return false;
+ }
+
+ ASSERT(!hasCrossedThreshold(codeBlock));
+
+ // Compute the true total count.
+ double trueTotalCount = static_cast<double>(m_totalCount) + m_counter;
+
+ // Correct the threshold for current memory usage.
+ double threshold = applyMemoryUsageHeuristics(m_activeThreshold, codeBlock);
+
+ // Threshold must be non-negative and not NaN.
+ ASSERT(threshold >= 0);
+
+ // Adjust the threshold according to the number of executions we have already
+ // seen. This shouldn't go negative, but it might, because of round-off errors.
+ threshold -= trueTotalCount;
+
+ if (threshold <= 0) {
+ m_counter = 0;
+ m_totalCount = trueTotalCount;
+ return true;
+ }
+
+ if (threshold > std::numeric_limits<int32_t>::max())
+ threshold = std::numeric_limits<int32_t>::max();
+
+ m_counter = static_cast<int32_t>(-threshold);
+
+ m_totalCount = trueTotalCount + threshold;
+
+ return false;
+}
+
+void ExecutionCounter::reset()
+{
+ m_counter = 0;
+ m_totalCount = 0;
+ m_activeThreshold = 0;
+}
+
+} // namespace JSC
+
diff --git a/Source/JavaScriptCore/bytecode/ExecutionCounter.h b/Source/JavaScriptCore/bytecode/ExecutionCounter.h
new file mode 100644
index 000000000..d2ffbb649
--- /dev/null
+++ b/Source/JavaScriptCore/bytecode/ExecutionCounter.h
@@ -0,0 +1,83 @@
+/*
+ * 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 ExecutionCounter_h
+#define ExecutionCounter_h
+
+#include <wtf/SimpleStats.h>
+
+namespace JSC {
+
+class CodeBlock;
+
+class ExecutionCounter {
+public:
+ ExecutionCounter();
+ bool checkIfThresholdCrossedAndSet(CodeBlock*);
+ void setNewThreshold(int32_t threshold, CodeBlock*);
+ void deferIndefinitely();
+ static double applyMemoryUsageHeuristics(int32_t value, CodeBlock*);
+ static int32_t applyMemoryUsageHeuristicsAndConvertToInt(int32_t value, CodeBlock*);
+
+ static int32_t formattedTotalCount(float value)
+ {
+ union {
+ int32_t i;
+ float f;
+ } u;
+ u.f = value;
+ return u.i;
+ }
+
+private:
+ bool hasCrossedThreshold(CodeBlock*) const;
+ bool setThreshold(CodeBlock*);
+ void reset();
+
+public:
+
+ // NB. These are intentionally public because it will be modified from machine code.
+
+ // This counter is incremented by the JIT or LLInt. It starts out negative and is
+ // counted up until it becomes non-negative. At the start of a counting period,
+ // the threshold we wish to reach is m_totalCount + m_counter, in the sense that
+ // we will add X to m_totalCount and subtract X from m_counter.
+ int32_t m_counter;
+
+ // Counts the total number of executions we have seen plus the ones we've set a
+ // threshold for in m_counter. Because m_counter's threshold is negative, the
+ // total number of actual executions can always be computed as m_totalCount +
+ // m_counter.
+ float m_totalCount;
+
+ // This is the threshold we were originally targetting, without any correction for
+ // the memory usage heuristics.
+ int32_t m_activeThreshold;
+};
+
+} // namespace JSC
+
+#endif // ExecutionCounter_h
+
diff --git a/Source/JavaScriptCore/bytecode/Opcode.h b/Source/JavaScriptCore/bytecode/Opcode.h
index a47fa5e9b..45598f899 100644
--- a/Source/JavaScriptCore/bytecode/Opcode.h
+++ b/Source/JavaScriptCore/bytecode/Opcode.h
@@ -82,7 +82,6 @@ namespace JSC {
macro(op_bitand, 5) \
macro(op_bitxor, 5) \
macro(op_bitor, 5) \
- macro(op_bitnot, 3) \
\
macro(op_check_has_instance, 2) \
macro(op_instanceof, 5) \
diff --git a/Source/JavaScriptCore/bytecode/PredictedType.cpp b/Source/JavaScriptCore/bytecode/PredictedType.cpp
index 2b490c24e..b04ff1f57 100644
--- a/Source/JavaScriptCore/bytecode/PredictedType.cpp
+++ b/Source/JavaScriptCore/bytecode/PredictedType.cpp
@@ -153,8 +153,13 @@ const char* predictionToString(PredictedType value)
else
isTop = false;
- if (isTop)
- return "Top";
+ if (isTop) {
+ ptr = description;
+ ptr.strcat("Top");
+ }
+
+ if (value & PredictEmpty)
+ ptr.strcat("Empty");
*ptr++ = 0;
@@ -221,6 +226,8 @@ PredictedType predictionFromCell(JSCell* cell)
PredictedType predictionFromValue(JSValue value)
{
+ if (value.isEmpty())
+ return PredictEmpty;
if (value.isInt32())
return PredictInt32;
if (value.isDouble()) {
diff --git a/Source/JavaScriptCore/bytecode/PredictedType.h b/Source/JavaScriptCore/bytecode/PredictedType.h
index efbe9b30d..0b7916610 100644
--- a/Source/JavaScriptCore/bytecode/PredictedType.h
+++ b/Source/JavaScriptCore/bytecode/PredictedType.h
@@ -61,8 +61,10 @@ static const PredictedType PredictDoubleNaN = 0x00040000; // It's defini
static const PredictedType PredictDouble = 0x00060000; // It's either a non-NaN or a NaN double.
static const PredictedType PredictNumber = 0x00070000; // It's either an Int32 or a Double.
static const PredictedType PredictBoolean = 0x00080000; // It's definitely a Boolean.
-static const PredictedType PredictOther = 0x40000000; // It's definitely none of the above.
-static const PredictedType PredictTop = 0x7fffffff; // It can be any of the above.
+static const PredictedType PredictOther = 0x08000000; // It's definitely none of the above.
+static const PredictedType PredictTop = 0x0fffffff; // It can be any of the above.
+static const PredictedType PredictEmpty = 0x10000000; // It's definitely an empty value marker.
+static const PredictedType PredictEmptyOrTop = 0x1fffffff; // It can be any of the above.
static const PredictedType FixedIndexedStorageMask = PredictByteArray | PredictInt8Array | PredictInt16Array | PredictInt32Array | PredictUint8Array | PredictUint8ClampedArray | PredictUint16Array | PredictUint32Array | PredictFloat32Array | PredictFloat64Array;
typedef bool (*PredictionChecker)(PredictedType);
@@ -89,7 +91,7 @@ inline bool isFinalObjectOrOtherPrediction(PredictedType value)
inline bool isFixedIndexedStorageObjectPrediction(PredictedType value)
{
- return (value & FixedIndexedStorageMask) == value;
+ return !!value && (value & FixedIndexedStorageMask) == value;
}
inline bool isStringPrediction(PredictedType value)
@@ -199,7 +201,7 @@ inline bool isDoubleRealPrediction(PredictedType value)
inline bool isDoublePrediction(PredictedType value)
{
- return (value & PredictDouble) == value;
+ return !!value && (value & PredictDouble) == value;
}
inline bool isNumberPrediction(PredictedType value)
@@ -217,6 +219,11 @@ inline bool isOtherPrediction(PredictedType value)
return value == PredictOther;
}
+inline bool isEmptyPrediction(PredictedType value)
+{
+ return value == PredictEmpty;
+}
+
const char* predictionToString(PredictedType value);
// Merge two predictions. Note that currently this just does left | right. It may
diff --git a/Source/JavaScriptCore/bytecode/SamplingTool.cpp b/Source/JavaScriptCore/bytecode/SamplingTool.cpp
index 077f041f4..f07dc79fb 100644
--- a/Source/JavaScriptCore/bytecode/SamplingTool.cpp
+++ b/Source/JavaScriptCore/bytecode/SamplingTool.cpp
@@ -100,7 +100,7 @@ SamplingRegion::Locker::Locker()
#endif
continue;
}
- if (WTF::weakCompareAndSwap(&s_currentOrReserved, previous, previous | 1))
+ if (WTF::weakCompareAndSwapUIntPtr(&s_currentOrReserved, previous, previous | 1))
break;
}
}
@@ -113,7 +113,7 @@ SamplingRegion::Locker::~Locker()
uintptr_t previous;
do {
previous = s_currentOrReserved;
- } while (!WTF::weakCompareAndSwap(&s_currentOrReserved, previous, previous & ~1));
+ } while (!WTF::weakCompareAndSwapUIntPtr(&s_currentOrReserved, previous, previous & ~1));
}
void SamplingRegion::sample()
diff --git a/Source/JavaScriptCore/bytecode/SamplingTool.h b/Source/JavaScriptCore/bytecode/SamplingTool.h
index 28fd528d0..fcb1986fd 100644
--- a/Source/JavaScriptCore/bytecode/SamplingTool.h
+++ b/Source/JavaScriptCore/bytecode/SamplingTool.h
@@ -148,7 +148,7 @@ namespace JSC {
if (previousPtr)
*previousPtr = bitwise_cast<SamplingRegion*>(previous);
- if (WTF::weakCompareAndSwap(&s_currentOrReserved, previous, bitwise_cast<uintptr_t>(current)))
+ if (WTF::weakCompareAndSwapUIntPtr(&s_currentOrReserved, previous, bitwise_cast<uintptr_t>(current)))
break;
}
}
diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
index 6fa0ce96b..4a6f4653e 100644
--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
@@ -119,6 +119,15 @@ namespace JSC {
expected by the callee.
*/
+void Label::setLocation(unsigned location)
+{
+ m_location = 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;
+}
+
#ifndef NDEBUG
void ResolveResult::checkValidity()
{
@@ -171,8 +180,8 @@ JSObject* BytecodeGenerator::generate()
m_codeBlock->setThisRegister(m_thisRegister.index());
m_scopeNode->emitBytecode(*this);
-
- m_codeBlock->setInstructionCount(m_codeBlock->instructions().size());
+
+ m_codeBlock->instructions() = RefCountedArray<Instruction>(m_instructions);
if (s_dumpsGeneratedCode)
m_codeBlock->dump(m_scopeChain->globalObject->globalExec());
@@ -607,7 +616,7 @@ PassRefPtr<Label> BytecodeGenerator::newLabel()
m_labels.removeLast();
// Allocate new label ID.
- m_labels.append(m_codeBlock);
+ m_labels.append(this);
return &m_labels.last();
}
diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
index d61b42b76..e7fe236e5 100644
--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
@@ -32,7 +32,7 @@
#define BytecodeGenerator_h
#include "CodeBlock.h"
-#include "HashTraits.h"
+#include <wtf/HashTraits.h>
#include "Instruction.h"
#include "Label.h"
#include "LabelScope.h"
@@ -48,6 +48,7 @@
namespace JSC {
class Identifier;
+ class Label;
class ScopeChainNode;
class CallArguments {
@@ -532,6 +533,8 @@ namespace JSC {
ScopeChainNode* scopeChain() const { return m_scopeChain.get(); }
private:
+ friend class Label;
+
void emitOpcode(OpcodeID);
ValueProfile* emitProfiledOpcode(OpcodeID);
void retrieveLastBinaryOp(int& dstIndex, int& src1Index, int& src2Index);
@@ -611,7 +614,7 @@ namespace JSC {
RegisterID* emitInitLazyRegister(RegisterID*);
- Vector<Instruction>& instructions() { return m_codeBlock->instructions(); }
+ Vector<Instruction>& instructions() { return m_instructions; }
SymbolTable& symbolTable() { return *m_symbolTable; }
bool shouldOptimizeLocals()
@@ -644,6 +647,8 @@ namespace JSC {
void createArgumentsIfNecessary();
void createActivationIfNecessary();
RegisterID* createLazyRegisterIfNecessary(RegisterID*);
+
+ Vector<Instruction> m_instructions;
bool m_shouldEmitDebugHooks;
bool m_shouldEmitProfileHooks;
diff --git a/Source/JavaScriptCore/bytecompiler/Label.h b/Source/JavaScriptCore/bytecompiler/Label.h
index 8cab1dbc0..21fa46309 100644
--- a/Source/JavaScriptCore/bytecompiler/Label.h
+++ b/Source/JavaScriptCore/bytecompiler/Label.h
@@ -39,21 +39,14 @@ namespace JSC {
class Label {
public:
- explicit Label(CodeBlock* codeBlock)
+ explicit Label(BytecodeGenerator* generator)
: m_refCount(0)
, m_location(invalidLocation)
- , m_codeBlock(codeBlock)
+ , m_generator(generator)
{
}
- void setLocation(unsigned location)
- {
- m_location = location;
-
- unsigned size = m_unresolvedJumps.size();
- for (unsigned i = 0; i < size; ++i)
- m_codeBlock->instructions()[m_unresolvedJumps[i].second].u.operand = m_location - m_unresolvedJumps[i].first;
- }
+ void setLocation(unsigned);
int bind(int opcode, int offset) const
{
@@ -81,7 +74,7 @@ namespace JSC {
int m_refCount;
unsigned m_location;
- CodeBlock* m_codeBlock;
+ BytecodeGenerator* m_generator;
mutable JumpVector m_unresolvedJumps;
};
diff --git a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
index 2d4181912..bb95cafb6 100644
--- a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
+++ b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
@@ -871,7 +871,15 @@ RegisterID* UnaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID*
return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src);
}
-
+// ------------------------------ BitwiseNotNode -----------------------------------
+
+RegisterID* BitwiseNotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ RefPtr<RegisterID> src2 = generator.emitLoad(generator.newTemporary(), jsNumber(-1));
+ RegisterID* src1 = generator.emitNode(m_expr);
+ return generator.emitBinaryOp(op_bitxor, generator.finalDestination(dst, src1), src1, src2.get(), OperandTypes(m_expr->resultDescriptor(), ResultType::numberTypeIsInt32()));
+}
+
// ------------------------------ LogicalNotNode -----------------------------------
void LogicalNotNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue)
@@ -2009,8 +2017,8 @@ RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
inline void ScopeNode::emitStatementsBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- if (m_data->m_statements)
- m_data->m_statements->emitBytecode(generator, dst);
+ if (m_statements)
+ m_statements->emitBytecode(generator, dst);
}
// ------------------------------ ProgramNode -----------------------------
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
index ee0cc9ab7..7ab05f329 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
+++ b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
@@ -54,13 +54,7 @@ AbstractState::AbstractState(Graph& graph)
, m_variables(m_codeBlock->numParameters(), graph.m_localVars)
, m_block(0)
{
- size_t maxBlockSize = 0;
- for (size_t i = 0; i < graph.m_blocks.size(); ++i) {
- BasicBlock* block = graph.m_blocks[i].get();
- if (block->end - block->begin > maxBlockSize)
- maxBlockSize = block->end - block->begin;
- }
- m_nodes.resize(maxBlockSize);
+ m_nodes.resize(graph.size());
}
AbstractState::~AbstractState() { }
@@ -75,8 +69,9 @@ void AbstractState::beginBasicBlock(BasicBlock* basicBlock)
ASSERT(basicBlock->variablesAtTail.numberOfLocals() == basicBlock->valuesAtTail.numberOfLocals());
ASSERT(basicBlock->variablesAtHead.numberOfLocals() == basicBlock->variablesAtTail.numberOfLocals());
- for (size_t i = 0; i < basicBlock->end - basicBlock->begin; ++i)
- m_nodes[i].clear();
+ for (size_t i = 0; i < basicBlock->size(); i++)
+ m_nodes[basicBlock->at(i)].clear();
+
m_variables = basicBlock->valuesAtHead;
m_haveStructures = false;
for (size_t i = 0; i < m_variables.numberOfArguments(); ++i) {
@@ -113,6 +108,11 @@ void AbstractState::initialize(Graph& graph)
continue;
}
+ if (graph.argumentIsCaptured(i)) {
+ root->valuesAtHead.argument(i).makeTop();
+ continue;
+ }
+
PredictedType prediction = node.variableAccessData()->prediction();
if (isInt32Prediction(prediction))
root->valuesAtHead.argument(i).set(PredictInt32);
@@ -143,6 +143,11 @@ void AbstractState::initialize(Graph& graph)
else
root->valuesAtHead.argument(i).makeTop();
}
+ for (size_t i = 0; i < root->valuesAtHead.numberOfLocals(); ++i) {
+ if (!graph.localIsCaptured(i))
+ continue;
+ root->valuesAtHead.local(i).makeTop();
+ }
}
bool AbstractState::endBasicBlock(MergeMode mergeMode)
@@ -164,14 +169,28 @@ bool AbstractState::endBasicBlock(MergeMode mergeMode)
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLog(" Merging state for argument %zu.\n", argument);
#endif
- changed |= mergeStateAtTail(block->valuesAtTail.argument(argument), m_variables.argument(argument), block->variablesAtTail.argument(argument));
+ AbstractValue& destination = block->valuesAtTail.argument(argument);
+ if (m_graph.argumentIsCaptured(argument)) {
+ if (!destination.isTop()) {
+ destination.makeTop();
+ changed = true;
+ }
+ } else
+ changed |= mergeStateAtTail(destination, m_variables.argument(argument), block->variablesAtTail.argument(argument));
}
for (size_t local = 0; local < block->variablesAtTail.numberOfLocals(); ++local) {
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLog(" Merging state for local %zu.\n", local);
#endif
- changed |= mergeStateAtTail(block->valuesAtTail.local(local), m_variables.local(local), block->variablesAtTail.local(local));
+ AbstractValue& destination = block->valuesAtTail.local(local);
+ if (m_graph.localIsCaptured(local)) {
+ if (!destination.isTop()) {
+ destination.makeTop();
+ changed = true;
+ }
+ } else
+ changed |= mergeStateAtTail(destination, m_variables.local(local), block->variablesAtTail.local(local));
}
}
@@ -191,12 +210,13 @@ void AbstractState::reset()
m_isValid = false;
}
-bool AbstractState::execute(NodeIndex nodeIndex)
+bool AbstractState::execute(unsigned indexInBlock)
{
PROFILE(FLAG_FOR_EXECUTION);
ASSERT(m_block);
ASSERT(m_isValid);
+ NodeIndex nodeIndex = m_block->at(indexInBlock);
Node& node = m_graph[nodeIndex];
if (!node.shouldGenerate())
@@ -216,11 +236,17 @@ bool AbstractState::execute(NodeIndex nodeIndex)
}
case GetLocal: {
- forNode(nodeIndex) = m_variables.operand(node.local());
+ if (m_graph.isCaptured(node.local()))
+ forNode(nodeIndex).makeTop();
+ else
+ forNode(nodeIndex) = m_variables.operand(node.local());
break;
}
case SetLocal: {
+ if (m_graph.isCaptured(node.local()))
+ break;
+
if (node.variableAccessData()->shouldUseDoubleFormat()) {
forNode(node.child1()).filter(PredictNumber);
m_variables.operand(node.local()).set(PredictDouble);
@@ -265,12 +291,12 @@ bool AbstractState::execute(NodeIndex nodeIndex)
break;
case ValueToInt32:
- if (!m_graph[node.child1()].shouldNotSpeculateInteger()) {
+ if (m_graph[node.child1()].shouldNotSpeculateInteger()) {
if (m_graph[node.child1()].shouldSpeculateDouble())
forNode(node.child1()).filter(PredictNumber);
- else
- forNode(node.child1()).filter(PredictInt32);
- }
+ } else
+ forNode(node.child1()).filter(PredictInt32);
+
forNode(nodeIndex).set(PredictInt32);
break;
@@ -289,7 +315,7 @@ bool AbstractState::execute(NodeIndex nodeIndex)
break;
}
if (node.op == ValueAdd) {
- clobberStructures(nodeIndex);
+ clobberStructures(indexInBlock);
forNode(nodeIndex).set(PredictString | PredictInt32 | PredictNumber);
break;
}
@@ -311,6 +337,17 @@ bool AbstractState::execute(NodeIndex nodeIndex)
break;
}
+ case ArithNegate: {
+ if (m_graph.negateShouldSpeculateInteger(node)) {
+ forNode(node.child1()).filter(PredictInt32);
+ forNode(nodeIndex).set(PredictInt32);
+ break;
+ }
+ forNode(node.child1()).filter(PredictNumber);
+ forNode(nodeIndex).set(PredictDouble);
+ break;
+ }
+
case ArithMul:
case ArithDiv:
case ArithMin:
@@ -368,7 +405,7 @@ bool AbstractState::execute(NodeIndex nodeIndex)
else if (child.shouldSpeculateNumber())
forNode(node.child1()).filter(PredictNumber);
else
- clobberStructures(nodeIndex);
+ clobberStructures(indexInBlock);
forNode(nodeIndex).set(PredictBoolean);
break;
}
@@ -391,7 +428,7 @@ bool AbstractState::execute(NodeIndex nodeIndex)
filter = PredictArray;
else {
filter = PredictTop;
- clobberStructures(nodeIndex);
+ clobberStructures(indexInBlock);
}
forNode(node.child1()).filter(filter);
forNode(node.child2()).filter(filter);
@@ -421,7 +458,7 @@ bool AbstractState::execute(NodeIndex nodeIndex)
break;
}
if (!isActionableArrayPrediction(m_graph[node.child1()].prediction()) || !m_graph[node.child2()].shouldSpeculateInteger()) {
- clobberStructures(nodeIndex);
+ clobberStructures(indexInBlock);
forNode(nodeIndex).makeTop();
break;
}
@@ -507,7 +544,7 @@ bool AbstractState::execute(NodeIndex nodeIndex)
}
if (!m_graph[node.child2()].shouldSpeculateInteger() || !isActionableMutableArrayPrediction(m_graph[node.child1()].prediction())) {
ASSERT(node.op == PutByVal);
- clobberStructures(nodeIndex);
+ clobberStructures(indexInBlock);
forNode(nodeIndex).makeTop();
break;
}
@@ -693,10 +730,25 @@ bool AbstractState::execute(NodeIndex nodeIndex)
}
case NewObject:
- forNode(nodeIndex).set(m_codeBlock->globalObject()->emptyObjectStructure());
+ forNode(nodeIndex).set(m_codeBlock->globalObjectFor(node.codeOrigin)->emptyObjectStructure());
m_haveStructures = true;
break;
-
+
+ case CreateActivation:
+ forNode(nodeIndex).set(m_graph.m_globalData.activationStructure.get());
+ m_haveStructures = true;
+ break;
+
+ case TearOffActivation:
+ // Does nothing that is user-visible.
+ break;
+
+ case NewFunction:
+ case NewFunctionExpression:
+ case NewFunctionNoCheck:
+ forNode(nodeIndex).set(m_codeBlock->globalObjectFor(node.codeOrigin)->functionStructure());
+ break;
+
case GetCallee:
forNode(nodeIndex).set(PredictFunction);
break;
@@ -710,7 +762,7 @@ bool AbstractState::execute(NodeIndex nodeIndex)
break;
case PutScopedVar:
- clobberStructures(nodeIndex);
+ clobberStructures(indexInBlock);
break;
case GetById:
@@ -721,7 +773,7 @@ bool AbstractState::execute(NodeIndex nodeIndex)
}
if (isCellPrediction(m_graph[node.child1()].prediction()))
forNode(node.child1()).filter(PredictCell);
- clobberStructures(nodeIndex);
+ clobberStructures(indexInBlock);
forNode(nodeIndex).makeTop();
break;
@@ -783,7 +835,7 @@ bool AbstractState::execute(NodeIndex nodeIndex)
break;
case PutStructure:
- clobberStructures(nodeIndex);
+ clobberStructures(indexInBlock);
forNode(node.child1()).set(node.structureTransitionData().newStructure);
m_haveStructures = true;
break;
@@ -874,7 +926,7 @@ bool AbstractState::execute(NodeIndex nodeIndex)
case PutById:
case PutByIdDirect:
forNode(node.child1()).filter(PredictCell);
- clobberStructures(nodeIndex);
+ clobberStructures(indexInBlock);
break;
case GetGlobalVar:
@@ -910,7 +962,7 @@ bool AbstractState::execute(NodeIndex nodeIndex)
case ResolveBase:
case ResolveBaseStrictPut:
case ResolveGlobal:
- clobberStructures(nodeIndex);
+ clobberStructures(indexInBlock);
forNode(nodeIndex).makeTop();
break;
@@ -927,13 +979,13 @@ bool AbstractState::execute(NodeIndex nodeIndex)
return m_isValid;
}
-inline void AbstractState::clobberStructures(NodeIndex nodeIndex)
+inline void AbstractState::clobberStructures(unsigned indexInBlock)
{
PROFILE(FLAG_FOR_STRUCTURE_CLOBBERING);
if (!m_haveStructures)
return;
- for (size_t i = nodeIndex - m_block->begin + 1; i-- > 0;)
- m_nodes[i].clobberStructures();
+ for (size_t i = indexInBlock + 1; i--;)
+ forNode(m_block->at(i)).clobberStructures();
for (size_t i = 0; i < m_variables.numberOfArguments(); ++i)
m_variables.argument(i).clobberStructures();
for (size_t i = 0; i < m_variables.numberOfLocals(); ++i)
@@ -946,7 +998,7 @@ inline bool AbstractState::mergeStateAtTail(AbstractValue& destination, Abstract
if (nodeIndex == NoNode)
return false;
- AbstractValue* source;
+ AbstractValue source;
Node& node = m_graph[nodeIndex];
if (!node.refCount())
@@ -961,7 +1013,7 @@ inline bool AbstractState::mergeStateAtTail(AbstractValue& destination, Abstract
case SetArgument:
case Flush:
// The block transfers the value from head to tail.
- source = &inVariable;
+ source = inVariable;
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLog(" Transfering from head to tail.\n");
#endif
@@ -969,7 +1021,7 @@ inline bool AbstractState::mergeStateAtTail(AbstractValue& destination, Abstract
case GetLocal:
// The block refines the value with additional speculations.
- source = &forNode(nodeIndex);
+ source = forNode(nodeIndex);
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLog(" Refining.\n");
#endif
@@ -978,7 +1030,10 @@ inline bool AbstractState::mergeStateAtTail(AbstractValue& destination, Abstract
case SetLocal:
// The block sets the variable, and potentially refines it, both
// before and after setting it.
- source = &forNode(node.child1());
+ if (node.variableAccessData()->shouldUseDoubleFormat())
+ source.set(PredictDouble);
+ else
+ source = forNode(node.child1());
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLog(" Setting.\n");
#endif
@@ -986,11 +1041,10 @@ inline bool AbstractState::mergeStateAtTail(AbstractValue& destination, Abstract
default:
ASSERT_NOT_REACHED();
- source = 0;
break;
}
- if (destination == *source) {
+ if (destination == source) {
// Abstract execution did not change the output value of the variable, for this
// basic block, on this iteration.
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
@@ -1002,7 +1056,7 @@ inline bool AbstractState::mergeStateAtTail(AbstractValue& destination, Abstract
// Abstract execution reached a new conclusion about the speculations reached about
// this variable after execution of this basic block. Update the state, and return
// true to indicate that the fixpoint must go on!
- destination = *source;
+ destination = source;
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLog(" Changed!\n");
#endif
@@ -1016,11 +1070,29 @@ inline bool AbstractState::merge(BasicBlock* from, BasicBlock* to)
bool changed = false;
- for (size_t argument = 0; argument < from->variablesAtTail.numberOfArguments(); ++argument)
- changed |= mergeVariableBetweenBlocks(to->valuesAtHead.argument(argument), from->valuesAtTail.argument(argument), to->variablesAtHead.argument(argument), from->variablesAtTail.argument(argument));
+ for (size_t argument = 0; argument < from->variablesAtTail.numberOfArguments(); ++argument) {
+ AbstractValue& destination = to->valuesAtHead.argument(argument);
+ if (m_graph.argumentIsCaptured(argument)) {
+ if (destination.isTop())
+ continue;
+ destination.makeTop();
+ changed = true;
+ continue;
+ }
+ changed |= mergeVariableBetweenBlocks(destination, from->valuesAtTail.argument(argument), to->variablesAtHead.argument(argument), from->variablesAtTail.argument(argument));
+ }
- for (size_t local = 0; local < from->variablesAtTail.numberOfLocals(); ++local)
- changed |= mergeVariableBetweenBlocks(to->valuesAtHead.local(local), from->valuesAtTail.local(local), to->variablesAtHead.local(local), from->variablesAtTail.local(local));
+ for (size_t local = 0; local < from->variablesAtTail.numberOfLocals(); ++local) {
+ AbstractValue& destination = to->valuesAtHead.local(local);
+ if (m_graph.localIsCaptured(local)) {
+ if (destination.isTop())
+ continue;
+ destination.makeTop();
+ changed = true;
+ continue;
+ }
+ changed |= mergeVariableBetweenBlocks(destination, from->valuesAtTail.local(local), to->variablesAtHead.local(local), from->variablesAtTail.local(local));
+ }
if (!to->cfaHasVisited)
changed = true;
@@ -1034,7 +1106,7 @@ inline bool AbstractState::mergeToSuccessors(Graph& graph, BasicBlock* basicBloc
{
PROFILE(FLAG_FOR_MERGE_TO_SUCCESSORS);
- Node& terminal = graph[basicBlock->end - 1];
+ Node& terminal = graph[basicBlock->last()];
ASSERT(terminal.isTerminal());
@@ -1073,15 +1145,17 @@ inline bool AbstractState::mergeVariableBetweenBlocks(AbstractValue& destination
void AbstractState::dump(FILE* out)
{
bool first = true;
- for (size_t i = 0; i < m_nodes.size(); ++i) {
- if (m_nodes[i].isClear())
+ for (size_t i = 0; i < m_block->size(); ++i) {
+ NodeIndex index = m_block->at(i);
+ AbstractValue& value = m_nodes[index];
+ if (value.isClear())
continue;
if (first)
first = false;
else
fprintf(out, " ");
- fprintf(out, "@%lu:", static_cast<unsigned long>(i + m_block->begin));
- m_nodes[i].dump(out);
+ fprintf(out, "@%lu:", static_cast<unsigned long>(index));
+ value.dump(out);
}
}
#endif
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractState.h b/Source/JavaScriptCore/dfg/DFGAbstractState.h
index 256e7495f..d9d5cc0f8 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractState.h
+++ b/Source/JavaScriptCore/dfg/DFGAbstractState.h
@@ -98,7 +98,7 @@ public:
AbstractValue& forNode(NodeIndex nodeIndex)
{
- return m_nodes[nodeIndex - m_block->begin];
+ return m_nodes[nodeIndex];
}
AbstractValue& forNode(NodeUse nodeUse)
@@ -152,7 +152,7 @@ public:
// if execution should continue past this node. Notably, it will return true
// for block terminals, so long as those terminals are not Return or variants
// of Throw.
- bool execute(NodeIndex);
+ bool execute(unsigned);
// Is the execution state still valid? This will be false if execute() has
// returned false previously.
@@ -163,20 +163,20 @@ public:
// that block must be abstractly interpreted again. This also sets
// to->cfaShouldRevisit to true, if it returns true, or if to has not been
// visited yet.
- static bool merge(BasicBlock* from, BasicBlock* to);
+ bool merge(BasicBlock* from, BasicBlock* to);
// Merge the abstract state stored at the block's tail into all of its
// successors. Returns true if any of the successors' states changed. Note
// that this is automatically called in endBasicBlock() if MergeMode is
// MergeToSuccessors.
- static bool mergeToSuccessors(Graph&, BasicBlock*);
+ bool mergeToSuccessors(Graph&, BasicBlock*);
#ifndef NDEBUG
void dump(FILE* out);
#endif
private:
- void clobberStructures(NodeIndex);
+ void clobberStructures(unsigned);
bool mergeStateAtTail(AbstractValue& destination, AbstractValue& inVariable, NodeIndex);
@@ -185,7 +185,7 @@ private:
CodeBlock* m_codeBlock;
Graph& m_graph;
- Vector<AbstractValue, 32> m_nodes;
+ Vector<AbstractValue, 64> m_nodes;
Operands<AbstractValue> m_variables;
BasicBlock* m_block;
bool m_haveStructures;
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractValue.h b/Source/JavaScriptCore/dfg/DFGAbstractValue.h
index aa5518187..682c7a90f 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractValue.h
+++ b/Source/JavaScriptCore/dfg/DFGAbstractValue.h
@@ -442,6 +442,11 @@ struct AbstractValue {
if (mergePredictions(m_type, predictionFromValue(value)) != m_type)
return false;
+ if (value.isEmpty()) {
+ ASSERT(m_type & PredictEmpty);
+ return true;
+ }
+
if (m_structure.isTop())
return true;
diff --git a/Source/JavaScriptCore/dfg/DFGArithNodeFlagsInferencePhase.cpp b/Source/JavaScriptCore/dfg/DFGArithNodeFlagsInferencePhase.cpp
index f55533a61..9a49364dd 100644
--- a/Source/JavaScriptCore/dfg/DFGArithNodeFlagsInferencePhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGArithNodeFlagsInferencePhase.cpp
@@ -80,11 +80,8 @@ private:
if (!node.shouldGenerate())
return;
- NodeType op = node.op;
- ArithNodeFlags flags = 0;
-
- if (node.hasArithNodeFlags())
- flags = node.rawArithNodeFlags();
+ NodeType op = static_cast<NodeType>(node.op);
+ NodeFlags flags = node.flags;
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLog(" %s @%u: %s ", Graph::opName(op), m_compileIndex, arithNodeFlagsAsString(flags));
@@ -131,6 +128,11 @@ private:
break;
}
+ case ArithNegate: {
+ changed |= m_graph[node.child1()].mergeArithNodeFlags(flags);
+ break;
+ }
+
case ArithMul:
case ArithDiv: {
// As soon as a multiply happens, we can easily end up in the part
@@ -173,7 +175,7 @@ private:
default:
flags |= NodeUsedAsNumber | NodeNeedsNegZero;
- if (op & NodeHasVarArgs) {
+ if (node.flags & NodeHasVarArgs) {
for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); childIdx++)
changed |= m_graph[m_graph.m_varArgChildren[childIdx]].mergeArithNodeFlags(flags);
} else {
@@ -217,6 +219,9 @@ private:
NodeIndex m_compileIndex;
bool m_changed;
+#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
+ unsigned m_count;
+#endif
};
void performArithNodeFlagsInference(Graph& graph)
diff --git a/Source/JavaScriptCore/dfg/DFGBasicBlock.h b/Source/JavaScriptCore/dfg/DFGBasicBlock.h
index 9d464bdc2..1c890b498 100644
--- a/Source/JavaScriptCore/dfg/DFGBasicBlock.h
+++ b/Source/JavaScriptCore/dfg/DFGBasicBlock.h
@@ -38,11 +38,9 @@ namespace JSC { namespace DFG {
typedef Vector <BlockIndex, 2> PredecessorList;
-struct BasicBlock {
- BasicBlock(unsigned bytecodeBegin, NodeIndex begin, unsigned numArguments, unsigned numLocals)
+struct BasicBlock : Vector<NodeIndex, 8> {
+ BasicBlock(unsigned bytecodeBegin, unsigned numArguments, unsigned numLocals)
: bytecodeBegin(bytecodeBegin)
- , begin(begin)
- , end(NoNode)
, isOSRTarget(false)
, cfaHasVisited(false)
, cfaShouldRevisit(false)
@@ -69,8 +67,6 @@ struct BasicBlock {
// for other purposes due to inlining.
unsigned bytecodeBegin;
- NodeIndex begin;
- NodeIndex end;
bool isOSRTarget;
bool cfaHasVisited;
bool cfaShouldRevisit;
@@ -79,6 +75,7 @@ struct BasicBlock {
#endif
bool isReachable;
+ Vector<NodeIndex> phis;
PredecessorList m_predecessors;
Operands<NodeIndex, NodeIndexTraits> variablesAtHead;
diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeCache.h b/Source/JavaScriptCore/dfg/DFGByteCodeCache.h
index fd3b5147f..f6a745c66 100644
--- a/Source/JavaScriptCore/dfg/DFGByteCodeCache.h
+++ b/Source/JavaScriptCore/dfg/DFGByteCodeCache.h
@@ -138,7 +138,6 @@ public:
delete iter->second.codeBlock;
continue;
}
- iter->second.codeBlock->m_shouldDiscardBytecode = iter->second.oldValueOfShouldDiscardBytecode;
}
}
@@ -155,7 +154,6 @@ public:
value.codeBlock = key.executable()->codeBlockWithBytecodeFor(key.kind());
if (value.codeBlock) {
value.owned = false;
- value.oldValueOfShouldDiscardBytecode = value.codeBlock->m_shouldDiscardBytecode;
} else {
// Nope, so try to parse one.
JSObject* exception;
@@ -171,13 +169,6 @@ public:
value.codeBlock = 0;
}
- // If we're about to return a code block, make sure that we're not going
- // to be discarding its bytecode if a GC were to happen during DFG
- // compilation. That's unlikely, but it's good to thoroughly enjoy this
- // kind of paranoia.
- if (!!value.codeBlock)
- value.codeBlock->m_shouldDiscardBytecode = false;
-
m_map.add(key, value);
return value.codeBlock;
diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
index 0e575db4e..3a3678d12 100644
--- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
+++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
@@ -66,6 +66,7 @@ public:
, m_globalResolveNumber(0)
, m_inlineStackTop(0)
, m_haveBuiltOperandMaps(false)
+ , m_emptyJSValueIndex(UINT_MAX)
{
ASSERT(m_profiledBlock);
@@ -185,16 +186,32 @@ private:
// Two possibilities: either the block wants the local to be live
// but has not loaded its value, or it has loaded its value, in
// which case we're done.
- Node& flushChild = m_graph[nodePtr->child1()];
+ nodeIndex = nodePtr->child1().index();
+ Node& flushChild = m_graph[nodeIndex];
if (flushChild.op == Phi) {
VariableAccessData* variableAccessData = flushChild.variableAccessData();
- nodeIndex = injectLazyOperandPrediction(addToGraph(GetLocal, OpInfo(variableAccessData), nodePtr->child1().index()));
+ nodeIndex = injectLazyOperandPrediction(addToGraph(GetLocal, OpInfo(variableAccessData), nodeIndex));
m_currentBlock->variablesAtTail.local(operand) = nodeIndex;
return nodeIndex;
}
nodePtr = &flushChild;
}
+
+ ASSERT(&m_graph[nodeIndex] == nodePtr);
ASSERT(nodePtr->op != Flush);
+
+ if (m_graph.localIsCaptured(operand)) {
+ // We wish to use the same variable access data as the previous access,
+ // but for all other purposes we want to issue a load since for all we
+ // know, at this stage of compilation, the local has been clobbered.
+
+ // Make sure we link to the Phi node, not to the GetLocal.
+ if (nodePtr->op == GetLocal)
+ nodeIndex = nodePtr->child1().index();
+
+ return injectLazyOperandPrediction(addToGraph(GetLocal, OpInfo(nodePtr->variableAccessData()), nodeIndex));
+ }
+
if (nodePtr->op == GetLocal)
return nodeIndex;
ASSERT(nodePtr->op == SetLocal);
@@ -218,7 +235,11 @@ private:
}
void setLocal(unsigned operand, NodeIndex value)
{
- m_currentBlock->variablesAtTail.local(operand) = addToGraph(SetLocal, OpInfo(newVariableAccessData(operand)), value);
+ VariableAccessData* variableAccessData = newVariableAccessData(operand);
+ NodeIndex nodeIndex = addToGraph(SetLocal, OpInfo(variableAccessData), value);
+ m_currentBlock->variablesAtTail.local(operand) = nodeIndex;
+ if (m_graph.localIsCaptured(operand))
+ addToGraph(Flush, OpInfo(variableAccessData), nodeIndex);
}
// Used in implementing get/set, above, where the operand is an argument.
@@ -226,7 +247,7 @@ private:
{
unsigned argument = operandToArgument(operand);
ASSERT(argument < m_numArguments);
-
+
NodeIndex nodeIndex = m_currentBlock->variablesAtTail.argument(argument);
if (nodeIndex != NoNode) {
@@ -235,16 +256,18 @@ private:
// Two possibilities: either the block wants the local to be live
// but has not loaded its value, or it has loaded its value, in
// which case we're done.
- Node& flushChild = m_graph[nodePtr->child1()];
+ nodeIndex = nodePtr->child1().index();
+ Node& flushChild = m_graph[nodeIndex];
if (flushChild.op == Phi) {
VariableAccessData* variableAccessData = flushChild.variableAccessData();
- nodeIndex = injectLazyOperandPrediction(addToGraph(GetLocal, OpInfo(variableAccessData), nodePtr->child1().index()));
+ nodeIndex = injectLazyOperandPrediction(addToGraph(GetLocal, OpInfo(variableAccessData), nodeIndex));
m_currentBlock->variablesAtTail.local(operand) = nodeIndex;
return nodeIndex;
}
nodePtr = &flushChild;
}
+ ASSERT(&m_graph[nodeIndex] == nodePtr);
ASSERT(nodePtr->op != Flush);
if (nodePtr->op == SetArgument) {
@@ -256,6 +279,12 @@ private:
return nodeIndex;
}
+ if (m_graph.argumentIsCaptured(argument)) {
+ if (nodePtr->op == GetLocal)
+ nodeIndex = nodePtr->child1().index();
+ return injectLazyOperandPrediction(addToGraph(GetLocal, OpInfo(nodePtr->variableAccessData()), nodeIndex));
+ }
+
if (nodePtr->op == GetLocal)
return nodeIndex;
@@ -278,11 +307,15 @@ private:
{
unsigned argument = operandToArgument(operand);
ASSERT(argument < m_numArguments);
-
- m_currentBlock->variablesAtTail.argument(argument) = addToGraph(SetLocal, OpInfo(newVariableAccessData(operand)), value);
+
+ VariableAccessData* variableAccessData = newVariableAccessData(operand);
+ NodeIndex nodeIndex = addToGraph(SetLocal, OpInfo(variableAccessData), value);
+ m_currentBlock->variablesAtTail.argument(argument) = nodeIndex;
+ if (m_graph.argumentIsCaptured(argument))
+ addToGraph(Flush, OpInfo(variableAccessData), nodeIndex);
}
- void flush(int operand)
+ void flushArgument(int operand)
{
// FIXME: This should check if the same operand had already been flushed to
// some other local variable.
@@ -308,7 +341,10 @@ private:
nodeIndex = node.child1().index();
ASSERT(m_graph[nodeIndex].op != Flush);
-
+
+ // Emit a Flush regardless of whether we already flushed it.
+ // This gives us guidance to see that the variable also needs to be flushed
+ // for arguments, even if it already had to be flushed for other reasons.
addToGraph(Flush, OpInfo(node.variableAccessData()), nodeIndex);
return;
}
@@ -533,8 +569,10 @@ private:
{
NodeIndex resultIndex = (NodeIndex)m_graph.size();
m_graph.append(Node(op, currentCodeOrigin(), child1, child2, child3));
+ ASSERT(op != Phi);
+ m_currentBlock->append(resultIndex);
- if (op & NodeMustGenerate)
+ if (defaultFlags(op) & NodeMustGenerate)
m_graph.ref(resultIndex);
return resultIndex;
}
@@ -542,8 +580,12 @@ private:
{
NodeIndex resultIndex = (NodeIndex)m_graph.size();
m_graph.append(Node(op, currentCodeOrigin(), info, child1, child2, child3));
+ if (op == Phi)
+ m_currentBlock->phis.append(resultIndex);
+ else
+ m_currentBlock->append(resultIndex);
- if (op & NodeMustGenerate)
+ if (defaultFlags(op) & NodeMustGenerate)
m_graph.ref(resultIndex);
return resultIndex;
}
@@ -551,8 +593,10 @@ private:
{
NodeIndex resultIndex = (NodeIndex)m_graph.size();
m_graph.append(Node(op, currentCodeOrigin(), info1, info2, child1, child2, child3));
+ ASSERT(op != Phi);
+ m_currentBlock->append(resultIndex);
- if (op & NodeMustGenerate)
+ if (defaultFlags(op) & NodeMustGenerate)
m_graph.ref(resultIndex);
return resultIndex;
}
@@ -561,13 +605,25 @@ private:
{
NodeIndex resultIndex = (NodeIndex)m_graph.size();
m_graph.append(Node(Node::VarArg, op, currentCodeOrigin(), info1, info2, m_graph.m_varArgChildren.size() - m_numPassedVarArgs, m_numPassedVarArgs));
+ ASSERT(op != Phi);
+ m_currentBlock->append(resultIndex);
m_numPassedVarArgs = 0;
- if (op & NodeMustGenerate)
+ if (defaultFlags(op) & NodeMustGenerate)
m_graph.ref(resultIndex);
return resultIndex;
}
+
+ NodeIndex insertPhiNode(OpInfo info, BasicBlock* block)
+ {
+ NodeIndex resultIndex = (NodeIndex)m_graph.size();
+ m_graph.append(Node(Phi, currentCodeOrigin(), info));
+ block->phis.append(resultIndex);
+
+ return resultIndex;
+ }
+
void addVarArgChild(NodeIndex child)
{
m_graph.m_varArgChildren.append(NodeUse(child));
@@ -643,13 +699,14 @@ private:
return nodeIndex;
#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLog("Making %s @%u safe at bc#%u because slow-case counter is at %u and exit profiles say %d, %d\n", Graph::opName(m_graph[nodeIndex].op), nodeIndex, m_currentIndex, m_inlineStackTop->m_profiledBlock->rareCaseProfileForBytecodeOffset(m_currentIndex)->m_counter, m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow), m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, NegativeZero));
+ dataLog("Making %s @%u safe at bc#%u because slow-case counter is at %u and exit profiles say %d, %d\n", Graph::opName(static_cast<NodeType>(m_graph[nodeIndex].op)), nodeIndex, m_currentIndex, m_inlineStackTop->m_profiledBlock->rareCaseProfileForBytecodeOffset(m_currentIndex)->m_counter, m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow), m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, NegativeZero));
#endif
switch (m_graph[nodeIndex].op) {
case UInt32ToNumber:
case ArithAdd:
case ArithSub:
+ case ArithNegate:
case ValueAdd:
case ArithMod: // for ArithMode "MayOverflow" means we tried to divide by zero, or we saw double.
m_graph[nodeIndex].mergeArithNodeFlags(NodeMayOverflow);
@@ -695,7 +752,7 @@ private:
return nodeIndex;
#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLog("Making %s @%u safe at bc#%u because special fast-case counter is at %u and exit profiles say %d, %d\n", Graph::opName(m_graph[nodeIndex].op), nodeIndex, m_currentIndex, m_inlineStackTop->m_profiledBlock->specialFastCaseProfileForBytecodeOffset(m_currentIndex)->m_counter, m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow), m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, NegativeZero));
+ dataLog("Making %s @%u safe at bc#%u because special fast-case counter is at %u and exit profiles say %d, %d\n", Graph::opName(static_cast<NodeType>(m_graph[nodeIndex].op)), nodeIndex, m_currentIndex, m_inlineStackTop->m_profiledBlock->specialFastCaseProfileForBytecodeOffset(m_currentIndex)->m_counter, m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow), m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, NegativeZero));
#endif
// FIXME: It might be possible to make this more granular. The DFG certainly can
@@ -912,6 +969,9 @@ private:
IdentifierMap 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;
// Cache of code blocks that we've generated bytecode for.
ByteCodeCache<canInlineFunctionFor> m_codeBlockCache;
@@ -1066,7 +1126,7 @@ bool ByteCodeParser::handleInlining(bool usesResult, int callTarget, NodeIndex c
// FIXME: Don't flush constants!
for (int i = 1; i < argumentCountIncludingThis; ++i)
- flush(registerOffset + argumentToOperand(i));
+ flushArgument(registerOffset + argumentToOperand(i));
int inlineCallFrameStart = m_inlineStackTop->remapOperand(registerOffset) - RegisterFile::CallFrameHeaderSize;
@@ -1129,7 +1189,7 @@ bool ByteCodeParser::handleInlining(bool usesResult, int callTarget, NodeIndex c
// the caller to continue in whatever basic block we're in right now.
if (!inlineStackEntry.m_didEarlyReturn && inlineStackEntry.m_didReturn) {
BasicBlock* lastBlock = m_graph.m_blocks.last().get();
- ASSERT(lastBlock->begin == lastBlock->end || !m_graph.last().isTerminal());
+ ASSERT(lastBlock->isEmpty() || !m_graph.last().isTerminal());
// 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.
@@ -1161,7 +1221,7 @@ bool ByteCodeParser::handleInlining(bool usesResult, int callTarget, NodeIndex c
continue;
BasicBlock* block = m_graph.m_blocks[inlineStackEntry.m_unlinkedBlocks[i].m_blockIndex].get();
ASSERT(!block->isLinked);
- Node& node = m_graph[block->end - 1];
+ Node& node = m_graph[block->last()];
ASSERT(node.op == Jump);
ASSERT(node.takenBlockIndex() == NoBlock);
node.setTakenBlockIndex(m_graph.m_blocks.size());
@@ -1172,7 +1232,7 @@ bool ByteCodeParser::handleInlining(bool usesResult, int callTarget, NodeIndex c
}
// Need to create a new basic block for the continuation at the caller.
- OwnPtr<BasicBlock> block = adoptPtr(new BasicBlock(nextOffset, m_graph.size(), m_numArguments, m_numLocals));
+ OwnPtr<BasicBlock> block = adoptPtr(new BasicBlock(nextOffset, m_numArguments, m_numLocals));
#if DFG_ENABLE(DEBUG_VERBOSE)
dataLog("Creating inline epilogue basic block %p, #%zu for %p bc#%u at inline depth %u.\n", block.get(), m_graph.m_blocks.size(), m_inlineStackTop->executable(), m_currentIndex, CodeOrigin::inlineDepthForCallFrame(m_inlineStackTop->m_inlineCallFrame));
#endif
@@ -1207,7 +1267,7 @@ bool ByteCodeParser::handleMinMax(bool usesResult, int resultOperand, NodeType o
}
if (argumentCountIncludingThis == 3) { // Math.min(x, y)
- set(resultOperand, addToGraph(op, OpInfo(NodeUseBottom), get(registerOffset + argumentToOperand(1)), get(registerOffset + argumentToOperand(2))));
+ set(resultOperand, addToGraph(op, get(registerOffset + argumentToOperand(1)), get(registerOffset + argumentToOperand(2))));
return true;
}
@@ -1235,7 +1295,7 @@ bool ByteCodeParser::handleIntrinsic(bool usesResult, int resultOperand, Intrins
if (!MacroAssembler::supportsFloatingPointAbs())
return false;
- NodeIndex nodeIndex = addToGraph(ArithAbs, OpInfo(NodeUseBottom), get(registerOffset + argumentToOperand(1)));
+ NodeIndex nodeIndex = addToGraph(ArithAbs, get(registerOffset + argumentToOperand(1)));
if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow))
m_graph[nodeIndex].mergeArithNodeFlags(NodeMayOverflow);
set(resultOperand, nodeIndex);
@@ -1364,7 +1424,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
// logic relies on every bytecode resulting in one or more nodes, which would
// be true anyway except for op_loop_hint, which emits a Phantom to force this
// to be true.
- if (m_currentBlock->begin != m_graph.size())
+ if (!m_currentBlock->isEmpty())
addToGraph(Jump, OpInfo(m_currentIndex));
else {
#if DFG_ENABLE(DEBUG_VERBOSE)
@@ -1502,11 +1562,11 @@ bool ByteCodeParser::parseBlock(unsigned limit)
if (valueOfInt32Constant(op2) & 0x1f)
result = addToGraph(BitURShift, op1, op2);
else
- result = makeSafe(addToGraph(UInt32ToNumber, OpInfo(NodeUseBottom), op1));
+ result = makeSafe(addToGraph(UInt32ToNumber, op1));
} else {
// Cannot optimize at this stage; shift & potentially rebox as a double.
result = addToGraph(BitURShift, op1, op2);
- result = makeSafe(addToGraph(UInt32ToNumber, OpInfo(NodeUseBottom), result));
+ result = makeSafe(addToGraph(UInt32ToNumber, result));
}
set(currentInstruction[1].u.operand, result);
NEXT_OPCODE(op_urshift);
@@ -1517,7 +1577,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
case op_pre_inc: {
unsigned srcDst = currentInstruction[1].u.operand;
NodeIndex op = get(srcDst);
- set(srcDst, makeSafe(addToGraph(ArithAdd, OpInfo(NodeUseBottom), op, one())));
+ set(srcDst, makeSafe(addToGraph(ArithAdd, op, one())));
NEXT_OPCODE(op_pre_inc);
}
@@ -1527,14 +1587,14 @@ bool ByteCodeParser::parseBlock(unsigned limit)
ASSERT(result != srcDst); // Required for assumptions we make during OSR.
NodeIndex op = get(srcDst);
set(result, op);
- set(srcDst, makeSafe(addToGraph(ArithAdd, OpInfo(NodeUseBottom), op, one())));
+ set(srcDst, makeSafe(addToGraph(ArithAdd, op, one())));
NEXT_OPCODE(op_post_inc);
}
case op_pre_dec: {
unsigned srcDst = currentInstruction[1].u.operand;
NodeIndex op = get(srcDst);
- set(srcDst, makeSafe(addToGraph(ArithSub, OpInfo(NodeUseBottom), op, one())));
+ set(srcDst, makeSafe(addToGraph(ArithSub, op, one())));
NEXT_OPCODE(op_pre_dec);
}
@@ -1543,7 +1603,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
unsigned srcDst = currentInstruction[2].u.operand;
NodeIndex op = get(srcDst);
set(result, op);
- set(srcDst, makeSafe(addToGraph(ArithSub, OpInfo(NodeUseBottom), op, one())));
+ set(srcDst, makeSafe(addToGraph(ArithSub, op, one())));
NEXT_OPCODE(op_post_dec);
}
@@ -1553,38 +1613,44 @@ bool ByteCodeParser::parseBlock(unsigned limit)
NodeIndex op1 = get(currentInstruction[2].u.operand);
NodeIndex op2 = get(currentInstruction[3].u.operand);
if (m_graph[op1].hasNumberResult() && m_graph[op2].hasNumberResult())
- set(currentInstruction[1].u.operand, makeSafe(addToGraph(ArithAdd, OpInfo(NodeUseBottom), op1, op2)));
+ set(currentInstruction[1].u.operand, makeSafe(addToGraph(ArithAdd, op1, op2)));
else
- set(currentInstruction[1].u.operand, makeSafe(addToGraph(ValueAdd, OpInfo(NodeUseBottom), op1, op2)));
+ set(currentInstruction[1].u.operand, makeSafe(addToGraph(ValueAdd, op1, op2)));
NEXT_OPCODE(op_add);
}
case op_sub: {
NodeIndex op1 = get(currentInstruction[2].u.operand);
NodeIndex op2 = get(currentInstruction[3].u.operand);
- set(currentInstruction[1].u.operand, makeSafe(addToGraph(ArithSub, OpInfo(NodeUseBottom), op1, op2)));
+ set(currentInstruction[1].u.operand, makeSafe(addToGraph(ArithSub, op1, op2)));
NEXT_OPCODE(op_sub);
}
+ case op_negate: {
+ NodeIndex op1 = get(currentInstruction[2].u.operand);
+ set(currentInstruction[1].u.operand, makeSafe(addToGraph(ArithNegate, op1)));
+ NEXT_OPCODE(op_negate);
+ }
+
case op_mul: {
// Multiply requires that the inputs are not truncated, unfortunately.
NodeIndex op1 = get(currentInstruction[2].u.operand);
NodeIndex op2 = get(currentInstruction[3].u.operand);
- set(currentInstruction[1].u.operand, makeSafe(addToGraph(ArithMul, OpInfo(NodeUseBottom), op1, op2)));
+ set(currentInstruction[1].u.operand, makeSafe(addToGraph(ArithMul, op1, op2)));
NEXT_OPCODE(op_mul);
}
case op_mod: {
NodeIndex op1 = get(currentInstruction[2].u.operand);
NodeIndex op2 = get(currentInstruction[3].u.operand);
- set(currentInstruction[1].u.operand, makeSafe(addToGraph(ArithMod, OpInfo(NodeUseBottom), op1, op2)));
+ set(currentInstruction[1].u.operand, makeSafe(addToGraph(ArithMod, op1, op2)));
NEXT_OPCODE(op_mod);
}
case op_div: {
NodeIndex op1 = get(currentInstruction[2].u.operand);
NodeIndex op2 = get(currentInstruction[3].u.operand);
- set(currentInstruction[1].u.operand, makeDivSafe(addToGraph(ArithDiv, OpInfo(NodeUseBottom), op1, op2)));
+ set(currentInstruction[1].u.operand, makeDivSafe(addToGraph(ArithDiv, op1, op2)));
NEXT_OPCODE(op_div);
}
@@ -2187,6 +2253,42 @@ bool ByteCodeParser::parseBlock(unsigned limit)
NEXT_OPCODE(op_loop_hint);
}
+
+ case op_init_lazy_reg: {
+ set(currentInstruction[1].u.operand, getJSConstantForValue(JSValue()));
+ NEXT_OPCODE(op_init_lazy_reg);
+ }
+
+ case op_create_activation: {
+ set(currentInstruction[1].u.operand, addToGraph(CreateActivation, get(currentInstruction[1].u.operand)));
+ NEXT_OPCODE(op_create_activation);
+ }
+
+ case op_tear_off_activation: {
+ // This currently ignores arguments because we don't support them yet.
+ addToGraph(TearOffActivation, get(currentInstruction[1].u.operand));
+ NEXT_OPCODE(op_tear_off_activation);
+ }
+
+ case op_new_func: {
+ if (!currentInstruction[3].u.operand) {
+ set(currentInstruction[1].u.operand,
+ addToGraph(NewFunctionNoCheck, OpInfo(currentInstruction[2].u.operand)));
+ } else {
+ set(currentInstruction[1].u.operand,
+ addToGraph(
+ NewFunction,
+ OpInfo(currentInstruction[2].u.operand),
+ get(currentInstruction[1].u.operand)));
+ }
+ NEXT_OPCODE(op_new_func);
+ }
+
+ case op_new_func_exp: {
+ set(currentInstruction[1].u.operand,
+ addToGraph(NewFunctionExpression, OpInfo(currentInstruction[2].u.operand)));
+ NEXT_OPCODE(op_new_func_exp);
+ }
default:
// Parse failed! This should not happen because the capabilities checker
@@ -2231,7 +2333,7 @@ void ByteCodeParser::processPhiStack()
dataLog(" Did not find node, adding phi.\n");
#endif
- valueInPredecessor = addToGraph(Phi, OpInfo(newVariableAccessData(stackType == ArgumentPhiStack ? argumentToOperand(varNo) : static_cast<int>(varNo))));
+ valueInPredecessor = insertPhiNode(OpInfo(newVariableAccessData(stackType == ArgumentPhiStack ? argumentToOperand(varNo) : static_cast<int>(varNo))), predecessorBlock);
var = valueInPredecessor;
if (stackType == ArgumentPhiStack)
predecessorBlock->variablesAtHead.setArgumentFirstTime(varNo, valueInPredecessor);
@@ -2255,7 +2357,11 @@ void ByteCodeParser::processPhiStack()
dataLog(" Found @%u.\n", valueInPredecessor);
#endif
}
- ASSERT(m_graph[valueInPredecessor].op == SetLocal || m_graph[valueInPredecessor].op == Phi || m_graph[valueInPredecessor].op == Flush || (m_graph[valueInPredecessor].op == SetArgument && stackType == ArgumentPhiStack));
+ ASSERT(m_graph[valueInPredecessor].op == SetLocal
+ || m_graph[valueInPredecessor].op == Phi
+ || m_graph[valueInPredecessor].op == Flush
+ || (m_graph[valueInPredecessor].op == SetArgument
+ && stackType == ArgumentPhiStack));
VariableAccessData* dataForPredecessor = m_graph[valueInPredecessor].variableAccessData();
@@ -2309,7 +2415,7 @@ void ByteCodeParser::processPhiStack()
continue;
}
- NodeIndex newPhi = addToGraph(Phi, OpInfo(dataForPhi));
+ NodeIndex newPhi = insertPhiNode(OpInfo(dataForPhi), entry.m_block);
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLog(" Splitting @%u, created @%u.\n", entry.m_phi, newPhi);
@@ -2349,10 +2455,9 @@ void ByteCodeParser::fixVariableAccessPredictions()
void ByteCodeParser::linkBlock(BasicBlock* block, Vector<BlockIndex>& possibleTargets)
{
- ASSERT(block->end != NoNode);
ASSERT(!block->isLinked);
- ASSERT(block->end > block->begin);
- Node& node = m_graph[block->end - 1];
+ ASSERT(!block->isEmpty());
+ Node& node = m_graph[block->last()];
ASSERT(node.isTerminal());
switch (node.op) {
@@ -2416,7 +2521,7 @@ void ByteCodeParser::determineReachability()
BasicBlock* block = m_graph.m_blocks[index].get();
ASSERT(block->isLinked);
- Node& node = m_graph[block->end - 1];
+ Node& node = m_graph[block->last()];
ASSERT(node.isTerminal());
if (node.isJump())
@@ -2435,8 +2540,13 @@ 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)
- m_jsValueMap.add(JSValue::encode(m_codeBlock->getConstant(i + FirstConstantRegisterIndex)), i + FirstConstantRegisterIndex);
+ 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;
}
@@ -2486,6 +2596,15 @@ ByteCodeParser::InlineStackEntry::InlineStackEntry(ByteCodeParser* byteCodeParse
}
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->m_codeBlock->addConstant(JSValue());
+ byteCodeParser->m_constants.append(ConstantRecord());
+ }
+ m_constantRemap[i] = byteCodeParser->m_emptyJSValueIndex;
+ continue;
+ }
pair<JSValueMap::iterator, bool> result = byteCodeParser->m_jsValueMap.add(JSValue::encode(value), byteCodeParser->m_codeBlock->numberOfConstantRegisters() + FirstConstantRegisterIndex);
if (result.second) {
byteCodeParser->m_codeBlock->addConstant(value);
@@ -2527,6 +2646,16 @@ void ByteCodeParser::parseCodeBlock()
{
CodeBlock* codeBlock = m_inlineStackTop->m_codeBlock;
+#if DFG_ENABLE(DEBUG_VERBOSE)
+ dataLog("Parsing code block %p. codeType = %s, numCapturedVars = %u, needsFullScopeChain = %s, needsActivation = %s, isStrictMode = %s\n",
+ codeBlock,
+ codeTypeToString(codeBlock->codeType()),
+ codeBlock->m_numCapturedVars,
+ codeBlock->needsFullScopeChain()?"true":"false",
+ codeBlock->ownerExecutable()->needsActivation()?"true":"false",
+ codeBlock->ownerExecutable()->isStrictMode()?"true":"false");
+#endif
+
for (unsigned jumpTargetIndex = 0; jumpTargetIndex <= codeBlock->numberOfJumpTargets(); ++jumpTargetIndex) {
// The maximum bytecode offset to go into the current basicblock is either the next jump target, or the end of the instructions.
unsigned limit = jumpTargetIndex < codeBlock->numberOfJumpTargets() ? codeBlock->jumpTarget(jumpTargetIndex) : codeBlock->instructions().size();
@@ -2539,7 +2668,7 @@ void ByteCodeParser::parseCodeBlock()
do {
if (!m_currentBlock) {
// Check if we can use the last block.
- if (!m_graph.m_blocks.isEmpty() && m_graph.m_blocks.last()->begin == m_graph.m_blocks.last()->end) {
+ if (!m_graph.m_blocks.isEmpty() && m_graph.m_blocks.last()->isEmpty()) {
// This must be a block belonging to us.
ASSERT(m_inlineStackTop->m_unlinkedBlocks.last().m_blockIndex == m_graph.m_blocks.size() - 1);
// Either the block is linkable or it isn't. If it's linkable then it's the last
@@ -2557,7 +2686,7 @@ void ByteCodeParser::parseCodeBlock()
#endif
m_currentBlock->bytecodeBegin = m_currentIndex;
} else {
- OwnPtr<BasicBlock> block = adoptPtr(new BasicBlock(m_currentIndex, m_graph.size(), m_numArguments, m_numLocals));
+ OwnPtr<BasicBlock> block = adoptPtr(new BasicBlock(m_currentIndex, m_numArguments, m_numLocals));
#if DFG_ENABLE(DEBUG_VERBOSE)
dataLog("Creating basic block %p, #%zu for %p bc#%u at inline depth %u.\n", block.get(), m_graph.m_blocks.size(), m_inlineStackTop->executable(), m_currentIndex, CodeOrigin::inlineDepthForCallFrame(m_inlineStackTop->m_inlineCallFrame));
#endif
@@ -2580,10 +2709,8 @@ 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->begin == m_graph.size() || m_graph.last().isTerminal() || (m_currentIndex == codeBlock->instructions().size() && m_inlineStackTop->m_inlineCallFrame) || !shouldContinueParsing);
+ ASSERT(m_currentBlock->isEmpty() || m_graph.last().isTerminal() || (m_currentIndex == codeBlock->instructions().size() && m_inlineStackTop->m_inlineCallFrame) || !shouldContinueParsing);
- m_currentBlock->end = m_graph.size();
-
if (!shouldContinueParsing)
return;
@@ -2600,6 +2727,11 @@ bool ByteCodeParser::parse()
// Set during construction.
ASSERT(!m_currentIndex);
+#if DFG_ENABLE(ALL_VARIABLES_CAPTURED)
+ // We should be pretending that the code has an activation.
+ ASSERT(m_graph.needsActivation());
+#endif
+
InlineStackEntry inlineStackEntry(this, m_codeBlock, m_profiledBlock, NoBlock, InvalidVirtualRegister, 0, InvalidVirtualRegister, InvalidVirtualRegister, CodeForCall);
parseCodeBlock();
diff --git a/Source/JavaScriptCore/dfg/DFGCCallHelpers.h b/Source/JavaScriptCore/dfg/DFGCCallHelpers.h
index 3481f99e8..16793bb46 100644
--- a/Source/JavaScriptCore/dfg/DFGCCallHelpers.h
+++ b/Source/JavaScriptCore/dfg/DFGCCallHelpers.h
@@ -420,6 +420,13 @@ public:
move(arg2, GPRInfo::argumentGPR2);
move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
}
+
+ ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, ImmPtr arg2)
+ {
+ move(arg1, GPRInfo::argumentGPR1);
+ move(arg2, GPRInfo::argumentGPR2);
+ move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+ }
ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2)
{
@@ -427,6 +434,13 @@ public:
move(arg1, GPRInfo::argumentGPR1);
move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
}
+
+ ALWAYS_INLINE void setupArgumentsWithExecState(ImmPtr arg1, GPRReg arg2)
+ {
+ move(arg2, GPRInfo::argumentGPR2); // Move this first, so setting arg1 does not trample!
+ move(arg1, GPRInfo::argumentGPR1);
+ move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+ }
ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2)
{
diff --git a/Source/JavaScriptCore/dfg/DFGCFAPhase.cpp b/Source/JavaScriptCore/dfg/DFGCFAPhase.cpp
index ac1e26c19..b4e75f808 100644
--- a/Source/JavaScriptCore/dfg/DFGCFAPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGCFAPhase.cpp
@@ -82,15 +82,16 @@ private:
dumpOperands(block->valuesAtHead, WTF::dataFile());
dataLog("\n");
#endif
- for (NodeIndex nodeIndex = block->begin; nodeIndex < block->end; ++nodeIndex) {
+ for (unsigned i = 0; i < block->size(); ++i) {
+ NodeIndex nodeIndex = block->at(i);
if (!m_graph[nodeIndex].shouldGenerate())
continue;
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLog(" %s @%u: ", Graph::opName(m_graph[nodeIndex].op), nodeIndex);
+ dataLog(" %s @%u: ", Graph::opName(static_cast<NodeType>(m_graph[nodeIndex].op)), nodeIndex);
m_state.dump(WTF::dataFile());
dataLog("\n");
#endif
- if (!m_state.execute(nodeIndex))
+ if (!m_state.execute(i))
break;
}
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
@@ -120,6 +121,9 @@ private:
AbstractState m_state;
bool m_changed;
+#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
+ unsigned m_count;
+#endif
};
void performCFA(Graph& graph)
diff --git a/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp b/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp
index a3c27ebc1..82e1b4609 100644
--- a/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp
@@ -43,9 +43,6 @@ public:
for (unsigned i = 0; i < m_graph.size(); ++i)
m_replacements[i] = NoNode;
-
- for (unsigned i = 0; i < LastNodeId; ++i)
- m_lastSeen[i] = NoNode;
}
void run()
@@ -71,68 +68,14 @@ private:
return canonicalize(nodeUse.indexUnchecked());
}
- // Computes where the search for a candidate for CSE should start. Don't call
- // this directly; call startIndex() instead as it does logging in debug mode.
- NodeIndex computeStartIndexForChildren(NodeIndex child1 = NoNode, NodeIndex child2 = NoNode, NodeIndex child3 = NoNode)
+ unsigned endIndexForPureCSE()
{
- const unsigned limit = 300;
-
- NodeIndex start = m_start;
- if (m_compileIndex - start > limit)
- start = m_compileIndex - limit;
-
- ASSERT(start >= m_start);
-
- NodeIndex child = canonicalize(child1);
- if (child == NoNode)
- return start;
-
- if (start < child)
- start = child;
-
- child = canonicalize(child2);
- if (child == NoNode)
- return start;
-
- if (start < child)
- start = child;
-
- child = canonicalize(child3);
- if (child == NoNode)
- return start;
-
- if (start < child)
- start = child;
-
- return start;
- }
-
- NodeIndex startIndexForChildren(NodeIndex child1 = NoNode, NodeIndex child2 = NoNode, NodeIndex child3 = NoNode)
- {
- NodeIndex result = computeStartIndexForChildren(child1, child2, child3);
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLog(" lookback %u: ", result);
-#endif
- return result;
- }
-
- NodeIndex startIndex()
- {
- Node& node = m_graph[m_compileIndex];
- return startIndexForChildren(
- node.child1().indexUnchecked(),
- node.child2().indexUnchecked(),
- node.child3().indexUnchecked());
- }
-
- NodeIndex endIndexForPureCSE()
- {
- NodeIndex result = m_lastSeen[m_graph[m_compileIndex].op & NodeIdMask];
- if (result == NoNode)
+ unsigned result = m_lastSeen[m_graph[m_compileIndex].op];
+ if (result == UINT_MAX)
result = 0;
else
result++;
- ASSERT(result <= m_compileIndex);
+ ASSERT(result <= m_indexInBlock);
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLog(" limit %u: ", result);
#endif
@@ -145,13 +88,16 @@ private:
NodeIndex child2 = canonicalize(node.child2());
NodeIndex child3 = canonicalize(node.child3());
- NodeIndex start = startIndex();
- for (NodeIndex index = endIndexForPureCSE(); index-- > start;) {
+ for (unsigned i = endIndexForPureCSE(); i--;) {
+ NodeIndex index = m_currentBlock->at(i);
+ if (index == child1 || index == child2 || index == child3)
+ break;
+
Node& otherNode = m_graph[index];
if (node.op != otherNode.op)
continue;
- if (node.arithNodeFlagsForCompare() != otherNode.arithNodeFlagsForCompare())
+ if (node.arithNodeFlags() != otherNode.arithNodeFlags())
continue;
NodeIndex otherChild = canonicalize(otherNode.child1());
@@ -201,9 +147,9 @@ private:
bool clobbersWorld(NodeIndex nodeIndex)
{
Node& node = m_graph[nodeIndex];
- if (node.op & NodeClobbersWorld)
+ if (node.flags & NodeClobbersWorld)
return true;
- if (!(node.op & NodeMightClobber))
+ if (!(node.flags & NodeMightClobber))
return false;
switch (node.op) {
case ValueAdd:
@@ -229,11 +175,14 @@ private:
NodeIndex child2 = canonicalize(node.child2());
NodeIndex child3 = canonicalize(node.child3());
- NodeIndex start = startIndex();
- for (NodeIndex index = m_compileIndex; index-- > start;) {
+ for (unsigned i = m_indexInBlock; i--;) {
+ NodeIndex index = m_currentBlock->at(i);
+ if (index == child1 || index == child2 || index == child3)
+ break;
+
Node& otherNode = m_graph[index];
if (node.op == otherNode.op
- && node.arithNodeFlagsForCompare() == otherNode.arithNodeFlagsForCompare()) {
+ && node.arithNodeFlags() == otherNode.arithNodeFlags()) {
NodeIndex otherChild = canonicalize(otherNode.child1());
if (otherChild == NoNode)
return index;
@@ -258,8 +207,8 @@ private:
NodeIndex globalVarLoadElimination(unsigned varNumber, JSGlobalObject* globalObject)
{
- NodeIndex start = startIndexForChildren();
- for (NodeIndex index = m_compileIndex; index-- > start;) {
+ for (unsigned i = m_indexInBlock; i--;) {
+ NodeIndex index = m_currentBlock->at(i);
Node& node = m_graph[index];
switch (node.op) {
case GetGlobalVar:
@@ -281,8 +230,11 @@ private:
NodeIndex getByValLoadElimination(NodeIndex child1, NodeIndex child2)
{
- NodeIndex start = startIndexForChildren(child1, child2);
- for (NodeIndex index = m_compileIndex; index-- > start;) {
+ for (unsigned i = m_indexInBlock; i--;) {
+ NodeIndex index = m_currentBlock->at(i);
+ if (index == child1 || index == canonicalize(child2))
+ break;
+
Node& node = m_graph[index];
switch (node.op) {
case GetByVal:
@@ -322,8 +274,11 @@ private:
bool checkFunctionElimination(JSFunction* function, NodeIndex child1)
{
- NodeIndex start = startIndexForChildren(child1);
- for (NodeIndex index = endIndexForPureCSE(); index-- > start;) {
+ for (unsigned i = endIndexForPureCSE(); i--;) {
+ NodeIndex index = m_currentBlock->at(i);
+ if (index == child1)
+ break;
+
Node& node = m_graph[index];
if (node.op == CheckFunction && node.child1() == child1 && node.function() == function)
return true;
@@ -333,8 +288,11 @@ private:
bool checkStructureLoadElimination(const StructureSet& structureSet, NodeIndex child1)
{
- NodeIndex start = startIndexForChildren(child1);
- for (NodeIndex index = m_compileIndex; index-- > start;) {
+ for (unsigned i = m_indexInBlock; i--;) {
+ NodeIndex index = m_currentBlock->at(i);
+ if (index == child1)
+ break;
+
Node& node = m_graph[index];
switch (node.op) {
case CheckStructure:
@@ -376,8 +334,11 @@ private:
NodeIndex getByOffsetLoadElimination(unsigned identifierNumber, NodeIndex child1)
{
- NodeIndex start = startIndexForChildren(child1);
- for (NodeIndex index = m_compileIndex; index-- > start;) {
+ for (unsigned i = m_indexInBlock; i--;) {
+ NodeIndex index = m_currentBlock->at(i);
+ if (index == child1)
+ break;
+
Node& node = m_graph[index];
switch (node.op) {
case GetByOffset:
@@ -419,8 +380,11 @@ private:
NodeIndex getPropertyStorageLoadElimination(NodeIndex child1)
{
- NodeIndex start = startIndexForChildren(child1);
- for (NodeIndex index = m_compileIndex; index-- > start;) {
+ for (unsigned i = m_indexInBlock; i--;) {
+ NodeIndex index = m_currentBlock->at(i);
+ if (index == child1)
+ break;
+
Node& node = m_graph[index];
switch (node.op) {
case GetPropertyStorage:
@@ -455,8 +419,11 @@ private:
NodeIndex getIndexedPropertyStorageLoadElimination(NodeIndex child1, bool hasIntegerIndexPrediction)
{
- NodeIndex start = startIndexForChildren(child1);
- for (NodeIndex index = m_compileIndex; index-- > start;) {
+ for (unsigned i = m_indexInBlock; i--;) {
+ NodeIndex index = m_currentBlock->at(i);
+ if (index == child1)
+ break;
+
Node& node = m_graph[index];
switch (node.op) {
case GetIndexedPropertyStorage: {
@@ -493,8 +460,8 @@ private:
NodeIndex getScopeChainLoadElimination(unsigned depth)
{
- NodeIndex start = startIndexForChildren();
- for (NodeIndex index = endIndexForPureCSE(); index-- > start;) {
+ for (unsigned i = endIndexForPureCSE(); i--;) {
+ NodeIndex index = m_currentBlock->at(i);
Node& node = m_graph[index];
if (node.op == GetScopeChain
&& node.scopeChainDepth() == depth)
@@ -539,7 +506,7 @@ private:
#endif
Node& node = m_graph[m_compileIndex];
- node.op = Phantom;
+ node.setOpAndDefaultFlags(Phantom);
node.setRefCount(1);
// At this point we will eliminate all references to this node.
@@ -555,14 +522,14 @@ private:
Node& node = m_graph[m_compileIndex];
ASSERT(node.refCount() == 1);
ASSERT(node.mustGenerate());
- node.op = Phantom;
+ node.setOpAndDefaultFlags(Phantom);
}
void performNodeCSE(Node& node)
{
bool shouldGenerate = node.shouldGenerate();
- if (node.op & NodeHasVarArgs) {
+ if (node.flags & NodeHasVarArgs) {
for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); childIdx++)
performSubstitution(m_graph.m_varArgChildren[childIdx], shouldGenerate);
} else {
@@ -575,7 +542,7 @@ private:
return;
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLog(" %s @%u: ", Graph::opName(m_graph[m_compileIndex].op), m_compileIndex);
+ dataLog(" %s @%u: ", Graph::opName(static_cast<NodeType>(m_graph[m_compileIndex].op)), m_compileIndex);
#endif
// NOTE: there are some nodes that we deliberately don't CSE even though we
@@ -598,6 +565,7 @@ private:
case BitURShift:
case ArithAdd:
case ArithSub:
+ case ArithNegate:
case ArithMul:
case ArithMod:
case ArithDiv:
@@ -701,7 +669,7 @@ private:
break;
}
- m_lastSeen[node.op & NodeIdMask] = m_compileIndex;
+ m_lastSeen[node.op] = m_indexInBlock;
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLog("\n");
#endif
@@ -709,16 +677,21 @@ private:
void performBlockCSE(BasicBlock& block)
{
- m_start = block.begin;
- NodeIndex end = block.end;
- for (m_compileIndex = m_start; m_compileIndex < end; ++m_compileIndex)
+ m_currentBlock = &block;
+ for (unsigned i = 0; i < LastNodeType; ++i)
+ m_lastSeen[i] = UINT_MAX;
+
+ for (m_indexInBlock = 0; m_indexInBlock < block.size(); ++m_indexInBlock) {
+ m_compileIndex = block[m_indexInBlock];
performNodeCSE(m_graph[m_compileIndex]);
+ }
}
- NodeIndex m_start;
+ BasicBlock* m_currentBlock;
NodeIndex m_compileIndex;
+ unsigned m_indexInBlock;
Vector<NodeIndex, 16> m_replacements;
- FixedArray<NodeIndex, LastNodeId> m_lastSeen;
+ FixedArray<unsigned, LastNodeType> m_lastSeen;
};
void performCSE(Graph& graph)
diff --git a/Source/JavaScriptCore/dfg/DFGCapabilities.h b/Source/JavaScriptCore/dfg/DFGCapabilities.h
index e339714e9..6509dbc3d 100644
--- a/Source/JavaScriptCore/dfg/DFGCapabilities.h
+++ b/Source/JavaScriptCore/dfg/DFGCapabilities.h
@@ -57,11 +57,13 @@ inline bool mightCompileFunctionForConstruct(CodeBlock* codeBlock)
inline bool mightInlineFunctionForCall(CodeBlock* codeBlock)
{
- return codeBlock->instructionCount() <= Options::maximumFunctionForCallInlineCandidateInstructionCount;
+ return codeBlock->instructionCount() <= Options::maximumFunctionForCallInlineCandidateInstructionCount
+ && !codeBlock->ownerExecutable()->needsActivation();
}
inline bool mightInlineFunctionForConstruct(CodeBlock* codeBlock)
{
- return codeBlock->instructionCount() <= Options::maximumFunctionForConstructInlineCandidateInstructionCount;
+ return codeBlock->instructionCount() <= Options::maximumFunctionForConstructInlineCandidateInstructionCount
+ && !codeBlock->ownerExecutable()->needsActivation();
}
// Opcode checking.
@@ -84,6 +86,7 @@ inline bool canCompileOpcode(OpcodeID opcodeID)
case op_post_dec:
case op_add:
case op_sub:
+ case op_negate:
case op_mul:
case op_mod:
case op_div:
@@ -151,21 +154,14 @@ inline bool canCompileOpcode(OpcodeID opcodeID)
case op_throw_reference_error:
case op_call:
case op_construct:
- return true;
-
- // Opcodes we support conditionally. Enabling these opcodes currently results in
- // performance regressions. Each node that we disable under restrictions has a
- // comment describing what we know about the regression so far.
-
- // Regresses string-validate-input, probably because it uses comparisons (< and >)
- // on strings, which currently will cause speculation failures in some cases.
case op_new_regexp:
-#if DFG_ENABLE(RESTRICTIONS)
- return false;
-#else
+ case op_init_lazy_reg:
+ case op_create_activation:
+ case op_tear_off_activation:
+ case op_new_func:
+ case op_new_func_exp:
return true;
-#endif
-
+
default:
return false;
}
@@ -191,6 +187,14 @@ inline bool canInlineOpcode(OpcodeID opcodeID)
case op_new_regexp:
return false;
+ // We don't support inlining code that creates activations or has nested functions.
+ case op_init_lazy_reg:
+ case op_create_activation:
+ case op_tear_off_activation:
+ case op_new_func:
+ case op_new_func_exp:
+ return false;
+
default:
return canCompileOpcode(opcodeID);
}
diff --git a/Source/JavaScriptCore/dfg/DFGCommon.h b/Source/JavaScriptCore/dfg/DFGCommon.h
index 330504c3e..8ff1e5cdd 100644
--- a/Source/JavaScriptCore/dfg/DFGCommon.h
+++ b/Source/JavaScriptCore/dfg/DFGCommon.h
@@ -53,7 +53,7 @@
#define DFG_ENABLE_CONSISTENCY_CHECK 0
// Emit a breakpoint into the head of every generated function, to aid debugging in GDB.
#define DFG_ENABLE_JIT_BREAK_ON_EVERY_FUNCTION 0
-// Emit a breakpoint into the head of every generated node, to aid debugging in GDB.
+// Emit a breakpoint into the head of every generated block, to aid debugging in GDB.
#define DFG_ENABLE_JIT_BREAK_ON_EVERY_BLOCK 0
// Emit a breakpoint into the head of every generated node, to aid debugging in GDB.
#define DFG_ENABLE_JIT_BREAK_ON_EVERY_NODE 0
@@ -69,10 +69,11 @@
#define DFG_ENABLE_OSR_ENTRY ENABLE(DFG_JIT)
// Generate stats on how successful we were in making use of the DFG jit, and remaining on the hot path.
#define DFG_ENABLE_SUCCESS_STATS 0
-// Used to enable conditionally supported opcodes that currently result in performance regressions.
-#define DFG_ENABLE_RESTRICTIONS 1
// Enable verification that the DFG is able to insert code for control flow edges.
#define DFG_ENABLE_EDGE_CODE_VERIFICATION 0
+// Pretend that all variables in the top-level code block got captured. Great
+// for testing code gen for activations.
+#define DFG_ENABLE_ALL_VARIABLES_CAPTURED 0
namespace JSC { namespace DFG {
diff --git a/Source/JavaScriptCore/dfg/DFGDriver.cpp b/Source/JavaScriptCore/dfg/DFGDriver.cpp
index 124d7e637..a0af3e6ad 100644
--- a/Source/JavaScriptCore/dfg/DFGDriver.cpp
+++ b/Source/JavaScriptCore/dfg/DFGDriver.cpp
@@ -34,6 +34,7 @@
#include "DFGCSEPhase.h"
#include "DFGJITCompiler.h"
#include "DFGPredictionPropagationPhase.h"
+#include "DFGRedundantPhiEliminationPhase.h"
#include "DFGVirtualRegisterAllocationPhase.h"
namespace JSC { namespace DFG {
@@ -58,6 +59,7 @@ inline bool compile(CompileMode compileMode, JSGlobalData& globalData, CodeBlock
if (compileMode == CompileFunction)
dfg.predictArgumentTypes();
+ performRedundantPhiElimination(dfg);
performArithNodeFlagsInference(dfg);
performPredictionPropagation(dfg);
performCSE(dfg);
@@ -70,18 +72,19 @@ inline bool compile(CompileMode compileMode, JSGlobalData& globalData, CodeBlock
#endif
JITCompiler dataFlowJIT(dfg);
+ bool result;
if (compileMode == CompileFunction) {
ASSERT(jitCodeWithArityCheck);
- dataFlowJIT.compileFunction(jitCode, *jitCodeWithArityCheck);
+ result = dataFlowJIT.compileFunction(jitCode, *jitCodeWithArityCheck);
} else {
ASSERT(compileMode == CompileOther);
ASSERT(!jitCodeWithArityCheck);
- dataFlowJIT.compile(jitCode);
+ result = dataFlowJIT.compile(jitCode);
}
- return true;
+ return result;
}
bool tryCompile(JSGlobalData& globalData, CodeBlock* codeBlock, JITCode& jitCode)
diff --git a/Source/JavaScriptCore/dfg/DFGGraph.cpp b/Source/JavaScriptCore/dfg/DFGGraph.cpp
index b8eec93c7..900251e10 100644
--- a/Source/JavaScriptCore/dfg/DFGGraph.cpp
+++ b/Source/JavaScriptCore/dfg/DFGGraph.cpp
@@ -41,7 +41,7 @@ static const char* dfgOpNames[] = {
const char *Graph::opName(NodeType op)
{
- return dfgOpNames[op & NodeIdMask];
+ return dfgOpNames[op];
}
const char* Graph::nameOfVariableAccessData(VariableAccessData* variableAccessData)
@@ -120,7 +120,7 @@ void Graph::dumpCodeOrigin(NodeIndex nodeIndex)
void Graph::dump(NodeIndex nodeIndex)
{
Node& node = at(nodeIndex);
- NodeType op = node.op;
+ NodeType op = static_cast<NodeType>(node.op);
unsigned refCount = node.refCount();
bool skipped = !refCount;
@@ -157,7 +157,7 @@ void Graph::dump(NodeIndex nodeIndex)
dataLog("-");
dataLog(">\t%s(", opName(op));
bool hasPrinted = false;
- if (op & NodeHasVarArgs) {
+ if (node.flags & NodeHasVarArgs) {
for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); childIdx++) {
if (hasPrinted)
dataLog(", ");
@@ -175,8 +175,8 @@ void Graph::dump(NodeIndex nodeIndex)
hasPrinted = !!node.child1();
}
- if (node.hasArithNodeFlags()) {
- dataLog("%s%s", hasPrinted ? ", " : "", arithNodeFlagsAsString(node.rawArithNodeFlags()));
+ if (node.arithNodeFlags()) {
+ dataLog("%s%s", hasPrinted ? ", " : "", arithNodeFlagsAsString(node.arithNodeFlags()));
hasPrinted = true;
}
if (node.hasVarNumber()) {
@@ -265,6 +265,12 @@ void Graph::dump()
for (size_t b = 0; b < m_blocks.size(); ++b) {
BasicBlock* block = m_blocks[b].get();
dataLog("Block #%u (bc#%u): %s%s\n", (int)b, block->bytecodeBegin, block->isReachable ? "" : " (skipped)", block->isOSRTarget ? " (OSR target)" : "");
+ dataLog(" Phi Nodes:\n");
+ for (size_t i = 0; i < block->phis.size(); ++i) {
+ // Dumping the dead Phi nodes is just annoying!
+ if (at(block->phis[i]).refCount())
+ dump(block->phis[i]);
+ }
dataLog(" vars before: ");
if (block->cfaHasVisited)
dumpOperands(block->valuesAtHead, WTF::dataFile());
@@ -274,8 +280,8 @@ void Graph::dump()
dataLog(" var links: ");
dumpOperands(block->variablesAtHead, WTF::dataFile());
dataLog("\n");
- for (size_t i = block->begin; i < block->end; ++i)
- dump(i);
+ for (size_t i = 0; i < block->size(); ++i)
+ dump(block->at(i));
dataLog(" vars after: ");
if (block->cfaHasVisited)
dumpOperands(block->valuesAtTail, WTF::dataFile());
@@ -283,15 +289,12 @@ void Graph::dump()
dataLog("<empty>");
dataLog("\n");
}
- dataLog("Phi Nodes:\n");
- for (size_t i = m_blocks.last()->end; i < size(); ++i)
- dump(i);
}
// FIXME: Convert this to be iterative, not recursive.
#define DO_TO_CHILDREN(node, thingToDo) do { \
Node& _node = (node); \
- if (_node.op & NodeHasVarArgs) { \
+ if (_node.flags & NodeHasVarArgs) { \
for (unsigned _childIdx = _node.firstChild(); \
_childIdx < _node.firstChild() + _node.numChildren(); \
_childIdx++) \
diff --git a/Source/JavaScriptCore/dfg/DFGGraph.h b/Source/JavaScriptCore/dfg/DFGGraph.h
index 88d6a4eec..bacbac827 100644
--- a/Source/JavaScriptCore/dfg/DFGGraph.h
+++ b/Source/JavaScriptCore/dfg/DFGGraph.h
@@ -177,6 +177,12 @@ public:
return Node::shouldSpeculateInteger(left, right) && add.canSpeculateInteger();
}
+ bool negateShouldSpeculateInteger(Node& negate)
+ {
+ ASSERT(negate.op == ArithNegate);
+ return at(negate.child1()).shouldSpeculateInteger() && negate.canSpeculateInteger();
+ }
+
bool addShouldSpeculateInteger(NodeIndex nodeIndex)
{
return addShouldSpeculateInteger(at(nodeIndex));
@@ -305,6 +311,41 @@ public:
return MethodOfGettingAValueProfile(valueProfileFor(nodeIndex));
}
+ bool needsActivation() const
+ {
+#if DFG_ENABLE(ALL_VARIABLES_CAPTURED)
+ return true;
+#else
+ return m_codeBlock->needsFullScopeChain() && m_codeBlock->codeType() != GlobalCode;
+#endif
+ }
+
+ // Pass an argument index. Currently it's ignored, but that's somewhat
+ // of a bug.
+ bool argumentIsCaptured(int) const
+ {
+ return needsActivation();
+ }
+ bool localIsCaptured(int operand) const
+ {
+#if DFG_ENABLE(ALL_VARIABLES_CAPTURED)
+ return operand < m_codeBlock->m_numVars;
+#else
+ return operand < m_codeBlock->m_numCapturedVars;
+#endif
+ }
+
+ bool isCaptured(int operand) const
+ {
+ if (operandIsArgument(operand))
+ return argumentIsCaptured(operandToArgument(operand));
+ return localIsCaptured(operand);
+ }
+ bool isCaptured(VirtualRegister virtualRegister) const
+ {
+ return isCaptured(static_cast<int>(virtualRegister));
+ }
+
JSGlobalData& m_globalData;
CodeBlock* m_codeBlock;
CodeBlock* m_profiledBlock;
diff --git a/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp b/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
index 7b2bbc788..af98f8d7a 100644
--- a/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
+++ b/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
@@ -44,7 +44,7 @@ void JITCompiler::linkOSRExits()
for (unsigned i = 0; i < codeBlock()->numberOfOSRExits(); ++i) {
OSRExit& exit = codeBlock()->osrExit(i);
exit.m_check.initialJump().link(this);
- store32(Imm32(i), &globalData()->osrExitIndex);
+ store32(TrustedImm32(i), &globalData()->osrExitIndex);
beginUninterruptedSequence();
exit.m_check.switchToLateJump(jump());
endUninterruptedSequence();
@@ -75,7 +75,7 @@ void JITCompiler::compileBody(SpeculativeJIT& speculative)
breakpoint();
#endif
- addPtr(Imm32(1), AbsoluteAddress(codeBlock()->addressOfSpeculativeSuccessCounter()));
+ addPtr(TrustedImm32(1), AbsoluteAddress(codeBlock()->addressOfSpeculativeSuccessCounter()));
bool compiledSpeculative = speculative.compile();
ASSERT_UNUSED(compiledSpeculative, compiledSpeculative);
@@ -195,7 +195,7 @@ void JITCompiler::link(LinkBuffer& linkBuffer)
codeBlock()->shrinkWeakReferenceTransitionsToFit();
}
-void JITCompiler::compile(JITCode& entry)
+bool JITCompiler::compile(JITCode& entry)
{
compileEntry();
SpeculativeJIT speculative(*this);
@@ -204,14 +204,17 @@ void JITCompiler::compile(JITCode& entry)
// Create OSR entry trampolines if necessary.
speculative.createOSREntries();
- LinkBuffer linkBuffer(*m_globalData, this, m_codeBlock);
+ LinkBuffer linkBuffer(*m_globalData, this, m_codeBlock, JITCompilationCanFail);
+ if (linkBuffer.didFailToAllocate())
+ return false;
link(linkBuffer);
speculative.linkOSREntries(linkBuffer);
entry = JITCode(linkBuffer.finalizeCode(), JITCode::DFGJIT);
+ return true;
}
-void JITCompiler::compileFunction(JITCode& entry, MacroAssemblerCodePtr& entryWithArityCheck)
+bool JITCompiler::compileFunction(JITCode& entry, MacroAssemblerCodePtr& entryWithArityCheck)
{
compileEntry();
@@ -222,7 +225,7 @@ void JITCompiler::compileFunction(JITCode& entry, MacroAssemblerCodePtr& entryWi
Label fromArityCheck(this);
// Plant a check that sufficient space is available in the RegisterFile.
// FIXME: https://bugs.webkit.org/show_bug.cgi?id=56291
- addPtr(Imm32(m_codeBlock->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister, GPRInfo::regT1);
+ addPtr(TrustedImm32(m_codeBlock->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister, GPRInfo::regT1);
Jump registerFileCheck = branchPtr(Below, AbsoluteAddress(m_globalData->interpreter->registerFile().addressOfEnd()), GPRInfo::regT1);
// Return here after register file check.
Label fromRegisterFileCheck = label();
@@ -258,7 +261,7 @@ void JITCompiler::compileFunction(JITCode& entry, MacroAssemblerCodePtr& entryWi
compileEntry();
load32(AssemblyHelpers::payloadFor((VirtualRegister)RegisterFile::ArgumentCount), GPRInfo::regT1);
- branch32(AboveOrEqual, GPRInfo::regT1, Imm32(m_codeBlock->numParameters())).linkTo(fromArityCheck, this);
+ branch32(AboveOrEqual, GPRInfo::regT1, TrustedImm32(m_codeBlock->numParameters())).linkTo(fromArityCheck, this);
move(stackPointerRegister, GPRInfo::argumentGPR0);
poke(GPRInfo::callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof(void*));
token = beginCall();
@@ -272,7 +275,9 @@ void JITCompiler::compileFunction(JITCode& entry, MacroAssemblerCodePtr& entryWi
// === Link ===
- LinkBuffer linkBuffer(*m_globalData, this, m_codeBlock);
+ LinkBuffer linkBuffer(*m_globalData, this, m_codeBlock, JITCompilationCanFail);
+ if (linkBuffer.didFailToAllocate())
+ return false;
link(linkBuffer);
speculative.linkOSREntries(linkBuffer);
@@ -282,6 +287,7 @@ void JITCompiler::compileFunction(JITCode& entry, MacroAssemblerCodePtr& entryWi
entryWithArityCheck = linkBuffer.locationOf(arityCheck);
entry = JITCode(linkBuffer.finalizeCode(), JITCode::DFGJIT);
+ return true;
}
} } // namespace JSC::DFG
diff --git a/Source/JavaScriptCore/dfg/DFGJITCompiler.h b/Source/JavaScriptCore/dfg/DFGJITCompiler.h
index a0c68fe4b..2df2703b0 100644
--- a/Source/JavaScriptCore/dfg/DFGJITCompiler.h
+++ b/Source/JavaScriptCore/dfg/DFGJITCompiler.h
@@ -194,8 +194,8 @@ public:
{
}
- void compile(JITCode& entry);
- void compileFunction(JITCode& entry, MacroAssemblerCodePtr& entryWithArityCheck);
+ bool compile(JITCode& entry);
+ bool compileFunction(JITCode& entry, MacroAssemblerCodePtr& entryWithArityCheck);
// Accessors for properties.
Graph& graph() { return m_graph; }
@@ -297,12 +297,13 @@ public:
// 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) {
- if (basicBlock.variablesAtHead.argument(argument) == NoNode)
+ NodeIndex nodeIndex = basicBlock.variablesAtHead.argument(argument);
+ if (nodeIndex == NoNode || !m_graph[nodeIndex].shouldGenerate())
entry->m_expectedValues.argument(argument).makeTop();
}
for (size_t local = 0; local < basicBlock.variablesAtHead.numberOfLocals(); ++local) {
NodeIndex nodeIndex = basicBlock.variablesAtHead.local(local);
- if (nodeIndex == NoNode)
+ if (nodeIndex == NoNode || !m_graph[nodeIndex].shouldGenerate())
entry->m_expectedValues.local(local).makeTop();
else if (m_graph[nodeIndex].variableAccessData()->shouldUseDoubleFormat())
entry->m_localsForcedDouble.set(local);
diff --git a/Source/JavaScriptCore/dfg/DFGNode.cpp b/Source/JavaScriptCore/dfg/DFGNode.cpp
new file mode 100644
index 000000000..c53817ba9
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGNode.cpp
@@ -0,0 +1,81 @@
+/*
+ * 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 "DFGNode.h"
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+const char* arithNodeFlagsAsString(NodeFlags flags)
+{
+ flags &= NodeArithMask;
+
+ if (!flags)
+ return "<empty>";
+
+ static const int size = 64;
+ static char description[size];
+ BoundsCheckedPointer<char> ptr(description, size);
+
+ bool hasPrinted = false;
+
+ if (flags & NodeUsedAsNumber) {
+ ptr.strcat("UsedAsNum");
+ hasPrinted = true;
+ }
+
+ if (flags & NodeNeedsNegZero) {
+ if (hasPrinted)
+ ptr.strcat("|");
+ ptr.strcat("NeedsNegZero");
+ hasPrinted = true;
+ }
+
+ if (flags & NodeMayOverflow) {
+ if (hasPrinted)
+ ptr.strcat("|");
+ ptr.strcat("MayOverflow");
+ hasPrinted = true;
+ }
+
+ if (flags & NodeMayNegZero) {
+ if (hasPrinted)
+ ptr.strcat("|");
+ ptr.strcat("MayNegZero");
+ hasPrinted = true;
+ }
+
+ *ptr++ = 0;
+
+ return description;
+}
+
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/Source/JavaScriptCore/dfg/DFGNode.h b/Source/JavaScriptCore/dfg/DFGNode.h
index 87dae7786..b672b67c5 100644
--- a/Source/JavaScriptCore/dfg/DFGNode.h
+++ b/Source/JavaScriptCore/dfg/DFGNode.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 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
@@ -57,36 +57,50 @@ struct StructureTransitionData {
}
};
-typedef unsigned ArithNodeFlags;
-#define NodeUseBottom 0x00
-#define NodeUsedAsNumber 0x01
-#define NodeNeedsNegZero 0x02
-#define NodeUsedAsMask 0x03
-#define NodeMayOverflow 0x04
-#define NodeMayNegZero 0x08
-#define NodeBehaviorMask 0x0c
+// Entries in the NodeType enum (below) are composed of an id, a result type (possibly none)
+// and some additional informative flags (must generate, is constant, etc).
+#define NodeResultMask 0xF
+#define NodeResultJS 0x1
+#define NodeResultNumber 0x2
+#define NodeResultInt32 0x3
+#define NodeResultBoolean 0x4
+#define NodeResultStorage 0x5
+#define NodeMustGenerate 0x10 // set on nodes that have side effects, and may not trivially be removed by DCE.
+#define NodeHasVarArgs 0x20
+#define NodeClobbersWorld 0x40
+#define NodeMightClobber 0x80
+#define NodeArithMask 0xF00
+#define NodeUseBottom 0x000
+#define NodeUsedAsNumber 0x100
+#define NodeNeedsNegZero 0x200
+#define NodeUsedAsMask 0x300
+#define NodeMayOverflow 0x400
+#define NodeMayNegZero 0x800
+#define NodeBehaviorMask 0xc00
-static inline bool nodeUsedAsNumber(ArithNodeFlags flags)
+typedef uint16_t NodeFlags;
+
+static inline bool nodeUsedAsNumber(NodeFlags flags)
{
return !!(flags & NodeUsedAsNumber);
}
-static inline bool nodeCanTruncateInteger(ArithNodeFlags flags)
+static inline bool nodeCanTruncateInteger(NodeFlags flags)
{
return !nodeUsedAsNumber(flags);
}
-static inline bool nodeCanIgnoreNegativeZero(ArithNodeFlags flags)
+static inline bool nodeCanIgnoreNegativeZero(NodeFlags flags)
{
return !(flags & NodeNeedsNegZero);
}
-static inline bool nodeMayOverflow(ArithNodeFlags flags)
+static inline bool nodeMayOverflow(NodeFlags flags)
{
return !!(flags & NodeMayOverflow);
}
-static inline bool nodeCanSpeculateInteger(ArithNodeFlags flags)
+static inline bool nodeCanSpeculateInteger(NodeFlags flags)
{
if (flags & NodeMayOverflow)
return !nodeUsedAsNumber(flags);
@@ -97,67 +111,7 @@ static inline bool nodeCanSpeculateInteger(ArithNodeFlags flags)
return true;
}
-static inline const char* arithNodeFlagsAsString(ArithNodeFlags flags)
-{
- if (!flags)
- return "<empty>";
-
- static const int size = 64;
- static char description[size];
- BoundsCheckedPointer<char> ptr(description, size);
-
- bool hasPrinted = false;
-
- if (flags & NodeUsedAsNumber) {
- ptr.strcat("UsedAsNum");
- hasPrinted = true;
- }
-
- if (flags & NodeNeedsNegZero) {
- if (hasPrinted)
- ptr.strcat("|");
- ptr.strcat("NeedsNegZero");
- hasPrinted = true;
- }
-
- if (flags & NodeMayOverflow) {
- if (hasPrinted)
- ptr.strcat("|");
- ptr.strcat("MayOverflow");
- hasPrinted = true;
- }
-
- if (flags & NodeMayNegZero) {
- if (hasPrinted)
- ptr.strcat("|");
- ptr.strcat("MayNegZero");
- hasPrinted = true;
- }
-
- *ptr++ = 0;
-
- return description;
-}
-
-// Entries in the NodeType enum (below) are composed of an id, a result type (possibly none)
-// and some additional informative flags (must generate, is constant, etc).
-#define NodeIdMask 0xFFF
-#define NodeResultMask 0xF000
-#define NodeMustGenerate 0x10000 // set on nodes that have side effects, and may not trivially be removed by DCE.
-#define NodeIsConstant 0x20000
-#define NodeIsJump 0x40000
-#define NodeIsBranch 0x80000
-#define NodeIsTerminal 0x100000
-#define NodeHasVarArgs 0x200000
-#define NodeClobbersWorld 0x400000
-#define NodeMightClobber 0x800000
-
-// These values record the result type of the node (as checked by NodeResultMask, above), 0 for no result.
-#define NodeResultJS 0x1000
-#define NodeResultNumber 0x2000
-#define NodeResultInt32 0x3000
-#define NodeResultBoolean 0x4000
-#define NodeResultStorage 0x5000
+const char* arithNodeFlagsAsString(NodeFlags);
// This macro defines a set of information about all known node types, used to populate NodeId, NodeType below.
#define FOR_EACH_DFG_OP(macro) \
@@ -204,6 +158,7 @@ static inline const char* arithNodeFlagsAsString(ArithNodeFlags flags)
/* Nodes for arithmetic operations. */\
macro(ArithAdd, NodeResultNumber) \
macro(ArithSub, NodeResultNumber) \
+ macro(ArithNegate, NodeResultNumber) \
macro(ArithMul, NodeResultNumber) \
macro(ArithDiv, NodeResultNumber) \
macro(ArithMod, NodeResultNumber) \
@@ -291,12 +246,23 @@ static inline const char* arithNodeFlagsAsString(ArithNodeFlags flags)
macro(ToPrimitive, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
macro(StrCat, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \
\
+ /* 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 for creating functions. */\
+ macro(NewFunctionNoCheck, NodeResultJS) \
+ macro(NewFunction, NodeResultJS) \
+ macro(NewFunctionExpression, NodeResultJS) \
+ \
/* Block terminals. */\
- macro(Jump, NodeMustGenerate | NodeIsTerminal | NodeIsJump) \
- macro(Branch, NodeMustGenerate | NodeIsTerminal | NodeIsBranch) \
- macro(Return, NodeMustGenerate | NodeIsTerminal) \
- macro(Throw, NodeMustGenerate | NodeIsTerminal) \
- macro(ThrowReferenceError, NodeMustGenerate | NodeIsTerminal) \
+ macro(Jump, NodeMustGenerate) \
+ macro(Branch, NodeMustGenerate) \
+ macro(Return, NodeMustGenerate) \
+ macro(Throw, NodeMustGenerate) \
+ macro(ThrowReferenceError, NodeMustGenerate) \
\
/* This is a pseudo-terminal. It means that execution should fall out of DFG at */\
/* this point, but execution does continue in the basic block - just in a */\
@@ -305,20 +271,25 @@ static inline const char* arithNodeFlagsAsString(ArithNodeFlags flags)
// 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).
-enum NodeId {
-#define DFG_OP_ENUM(opcode, flags) opcode##_id,
+enum NodeType {
+#define DFG_OP_ENUM(opcode, flags) opcode,
FOR_EACH_DFG_OP(DFG_OP_ENUM)
#undef DFG_OP_ENUM
- LastNodeId
+ LastNodeType
};
-// Entries in this enum describe all Node types.
-// The enum value contains a monotonically increasing id, a result type, and additional flags.
-enum NodeType {
-#define DFG_OP_ENUM(opcode, flags) opcode = opcode##_id | (flags),
+// Specifies the default flags for each node.
+inline NodeFlags defaultFlags(NodeType op)
+{
+ switch (op) {
+#define DFG_OP_ENUM(opcode, flags) case opcode: return flags;
FOR_EACH_DFG_OP(DFG_OP_ENUM)
#undef DFG_OP_ENUM
-};
+ default:
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
+}
// This type used in passing an immediate argument to Node constructor;
// distinguishes an immediate value (typically an index into a CodeBlock data structure -
@@ -341,34 +312,32 @@ struct Node {
// Construct a node with up to 3 children, no immediate value.
Node(NodeType op, CodeOrigin codeOrigin, NodeIndex child1 = NoNode, NodeIndex child2 = NoNode, NodeIndex child3 = NoNode)
- : op(op)
- , codeOrigin(codeOrigin)
+ : codeOrigin(codeOrigin)
, children(NodeReferenceBlob::Fixed, child1, child2, child3)
, m_virtualRegister(InvalidVirtualRegister)
, m_refCount(0)
, m_prediction(PredictNone)
{
- ASSERT(!(op & NodeHasVarArgs));
- ASSERT(!hasArithNodeFlags());
+ setOpAndDefaultFlags(op);
+ ASSERT(!(flags & NodeHasVarArgs));
}
// Construct a node with up to 3 children and an immediate value.
Node(NodeType op, CodeOrigin codeOrigin, OpInfo imm, NodeIndex child1 = NoNode, NodeIndex child2 = NoNode, NodeIndex child3 = NoNode)
- : op(op)
- , codeOrigin(codeOrigin)
+ : codeOrigin(codeOrigin)
, children(NodeReferenceBlob::Fixed, child1, child2, child3)
, m_virtualRegister(InvalidVirtualRegister)
, m_refCount(0)
, m_opInfo(imm.m_value)
, m_prediction(PredictNone)
{
- ASSERT(!(op & NodeHasVarArgs));
+ setOpAndDefaultFlags(op);
+ ASSERT(!(flags & NodeHasVarArgs));
}
// Construct a node with up to 3 children and two immediate values.
Node(NodeType op, CodeOrigin codeOrigin, OpInfo imm1, OpInfo imm2, NodeIndex child1 = NoNode, NodeIndex child2 = NoNode, NodeIndex child3 = NoNode)
- : op(op)
- , codeOrigin(codeOrigin)
+ : codeOrigin(codeOrigin)
, children(NodeReferenceBlob::Fixed, child1, child2, child3)
, m_virtualRegister(InvalidVirtualRegister)
, m_refCount(0)
@@ -376,13 +345,13 @@ struct Node {
, m_opInfo2(safeCast<unsigned>(imm2.m_value))
, m_prediction(PredictNone)
{
- ASSERT(!(op & NodeHasVarArgs));
+ setOpAndDefaultFlags(op);
+ ASSERT(!(flags & NodeHasVarArgs));
}
// Construct a node with a variable number of children and two immediate values.
Node(VarArgTag, NodeType op, CodeOrigin codeOrigin, OpInfo imm1, OpInfo imm2, unsigned firstChild, unsigned numChildren)
- : op(op)
- , codeOrigin(codeOrigin)
+ : codeOrigin(codeOrigin)
, children(NodeReferenceBlob::Variable, firstChild, numChildren)
, m_virtualRegister(InvalidVirtualRegister)
, m_refCount(0)
@@ -390,12 +359,19 @@ struct Node {
, m_opInfo2(safeCast<unsigned>(imm2.m_value))
, m_prediction(PredictNone)
{
- ASSERT(op & NodeHasVarArgs);
+ setOpAndDefaultFlags(op);
+ ASSERT(flags & NodeHasVarArgs);
+ }
+
+ void setOpAndDefaultFlags(NodeType op)
+ {
+ this->op = op;
+ flags = defaultFlags(op);
}
bool mustGenerate()
{
- return op & NodeMustGenerate;
+ return flags & NodeMustGenerate;
}
bool isConstant()
@@ -520,6 +496,7 @@ struct Node {
case UInt32ToNumber:
case ArithAdd:
case ArithSub:
+ case ArithNegate:
case ArithMul:
case ArithAbs:
case ArithMin:
@@ -533,44 +510,32 @@ struct Node {
}
}
- ArithNodeFlags rawArithNodeFlags()
- {
- ASSERT(hasArithNodeFlags());
- return m_opInfo;
- }
-
// 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.
- ArithNodeFlags arithNodeFlags()
+ NodeFlags arithNodeFlags()
{
- ArithNodeFlags result = rawArithNodeFlags();
+ NodeFlags result = flags & NodeArithMask;
if (op == ArithMul)
return result;
return result & ~NodeNeedsNegZero;
}
- ArithNodeFlags arithNodeFlagsForCompare()
- {
- if (hasArithNodeFlags())
- return arithNodeFlags();
- return 0;
- }
-
- void setArithNodeFlag(ArithNodeFlags flags)
+ void setArithNodeFlag(NodeFlags newFlags)
{
- ASSERT(hasArithNodeFlags());
- m_opInfo = flags;
+ ASSERT(!(newFlags & ~NodeArithMask));
+
+ flags &= ~NodeArithMask;
+ flags |= newFlags;
}
- bool mergeArithNodeFlags(ArithNodeFlags flags)
+ bool mergeArithNodeFlags(NodeFlags newFlags)
{
- if (!hasArithNodeFlags())
+ ASSERT(!(newFlags & ~NodeArithMask));
+ newFlags = flags | newFlags;
+ if (newFlags == flags)
return false;
- ArithNodeFlags newFlags = m_opInfo | flags;
- if (newFlags == m_opInfo)
- return false;
- m_opInfo = newFlags;
+ flags = newFlags;
return true;
}
@@ -626,42 +591,51 @@ struct Node {
bool hasResult()
{
- return op & NodeResultMask;
+ return flags & NodeResultMask;
}
bool hasInt32Result()
{
- return (op & NodeResultMask) == NodeResultInt32;
+ return (flags & NodeResultMask) == NodeResultInt32;
}
bool hasNumberResult()
{
- return (op & NodeResultMask) == NodeResultNumber;
+ return (flags & NodeResultMask) == NodeResultNumber;
}
bool hasJSResult()
{
- return (op & NodeResultMask) == NodeResultJS;
+ return (flags & NodeResultMask) == NodeResultJS;
}
bool hasBooleanResult()
{
- return (op & NodeResultMask) == NodeResultBoolean;
+ return (flags & NodeResultMask) == NodeResultBoolean;
}
bool isJump()
{
- return op & NodeIsJump;
+ return op == Jump;
}
bool isBranch()
{
- return op & NodeIsBranch;
+ return op == Branch;
}
bool isTerminal()
{
- return op & NodeIsTerminal;
+ switch (op) {
+ case Jump:
+ case Branch:
+ case Return:
+ case Throw:
+ case ThrowReferenceError:
+ return true;
+ default:
+ return false;
+ }
}
unsigned takenBytecodeOffsetDuringParsing()
@@ -775,6 +749,30 @@ struct Node {
unsigned storageAccessDataIndex()
{
+ ASSERT(hasStorageAccessData());
+ return m_opInfo;
+ }
+
+ bool hasFunctionDeclIndex()
+ {
+ return op == NewFunction
+ || op == NewFunctionNoCheck;
+ }
+
+ unsigned functionDeclIndex()
+ {
+ ASSERT(hasFunctionDeclIndex());
+ return m_opInfo;
+ }
+
+ bool hasFunctionExprIndex()
+ {
+ return op == NewFunctionExpression;
+ }
+
+ unsigned functionExprIndex()
+ {
+ ASSERT(hasFunctionExprIndex());
return m_opInfo;
}
@@ -799,7 +797,7 @@ struct Node {
bool shouldGenerate()
{
- return m_refCount && op != Phi && op != Flush;
+ return m_refCount;
}
unsigned refCount()
@@ -834,7 +832,7 @@ struct Node {
NodeUse child1()
{
- ASSERT(!(op & NodeHasVarArgs));
+ ASSERT(!(flags & NodeHasVarArgs));
return children.child1();
}
@@ -848,25 +846,25 @@ struct Node {
NodeUse child2()
{
- ASSERT(!(op & NodeHasVarArgs));
+ ASSERT(!(flags & NodeHasVarArgs));
return children.child2();
}
NodeUse child3()
{
- ASSERT(!(op & NodeHasVarArgs));
+ ASSERT(!(flags & NodeHasVarArgs));
return children.child3();
}
unsigned firstChild()
{
- ASSERT(op & NodeHasVarArgs);
+ ASSERT(flags & NodeHasVarArgs);
return children.firstChild();
}
unsigned numChildren()
{
- ASSERT(op & NodeHasVarArgs);
+ ASSERT(flags & NodeHasVarArgs);
return children.numChildren();
}
@@ -1032,8 +1030,8 @@ struct Node {
fprintf(out, ", @%u", child3().index());
}
- // This enum value describes the type of the node.
- NodeType op;
+ uint16_t op; // real type is NodeType
+ NodeFlags flags;
// Used to look up exception handling information (currently implemented as a bytecode index).
CodeOrigin codeOrigin;
// References to up to 3 children, or links to a variable length set of children.
diff --git a/Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp b/Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp
index a672234a3..bd45020d1 100644
--- a/Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp
@@ -98,7 +98,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, SpeculationRecovery* reco
m_jit.store32(scratch, &bitwise_cast<EncodedValueDescriptor*>(bucket)->asBits.payload);
m_jit.load32(scratchBuffer, scratch);
} else if (exit.m_jsValueSource.hasKnownTag()) {
- m_jit.store32(AssemblyHelpers::Imm32(exit.m_jsValueSource.tag()), &bitwise_cast<EncodedValueDescriptor*>(bucket)->asBits.tag);
+ 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);
} else {
m_jit.store32(exit.m_jsValueSource.tagGPR(), &bitwise_cast<EncodedValueDescriptor*>(bucket)->asBits.tag);
@@ -562,32 +562,40 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, SpeculationRecovery* reco
// counter to 0; otherwise we set the counter to
// counterValueForOptimizeAfterWarmUp().
- m_jit.add32(AssemblyHelpers::Imm32(1), AssemblyHelpers::AbsoluteAddress(&exit.m_count));
+ m_jit.add32(AssemblyHelpers::TrustedImm32(1), AssemblyHelpers::AbsoluteAddress(&exit.m_count));
m_jit.move(AssemblyHelpers::TrustedImmPtr(m_jit.codeBlock()), GPRInfo::regT0);
m_jit.load32(AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfSpeculativeFailCounter()), GPRInfo::regT2);
m_jit.load32(AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfSpeculativeSuccessCounter()), GPRInfo::regT1);
- m_jit.add32(AssemblyHelpers::Imm32(1), GPRInfo::regT2);
- m_jit.add32(AssemblyHelpers::Imm32(-1), GPRInfo::regT1);
+ m_jit.add32(AssemblyHelpers::TrustedImm32(1), GPRInfo::regT2);
+ m_jit.add32(AssemblyHelpers::TrustedImm32(-1), GPRInfo::regT1);
m_jit.store32(GPRInfo::regT2, AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfSpeculativeFailCounter()));
m_jit.store32(GPRInfo::regT1, AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfSpeculativeSuccessCounter()));
m_jit.move(AssemblyHelpers::TrustedImmPtr(m_jit.baselineCodeBlock()), GPRInfo::regT0);
- AssemblyHelpers::Jump fewFails = m_jit.branch32(AssemblyHelpers::BelowOrEqual, GPRInfo::regT2, AssemblyHelpers::Imm32(m_jit.codeBlock()->largeFailCountThreshold()));
- m_jit.mul32(AssemblyHelpers::Imm32(Options::desiredSpeculativeSuccessFailRatio), GPRInfo::regT2, GPRInfo::regT2);
+ AssemblyHelpers::Jump fewFails = m_jit.branch32(AssemblyHelpers::BelowOrEqual, GPRInfo::regT2, AssemblyHelpers::TrustedImm32(m_jit.codeBlock()->largeFailCountThreshold()));
+ m_jit.mul32(AssemblyHelpers::TrustedImm32(Options::desiredSpeculativeSuccessFailRatio), GPRInfo::regT2, GPRInfo::regT2);
AssemblyHelpers::Jump lowFailRate = m_jit.branch32(AssemblyHelpers::BelowOrEqual, GPRInfo::regT2, GPRInfo::regT1);
// Reoptimize as soon as possible.
- m_jit.store32(AssemblyHelpers::Imm32(Options::executionCounterValueForOptimizeNextInvocation), AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfJITExecuteCounter()));
+ m_jit.store32(AssemblyHelpers::TrustedImm32(0), AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfJITExecuteCounter()));
+ m_jit.store32(AssemblyHelpers::TrustedImm32(0), AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfJITExecutionActiveThreshold()));
AssemblyHelpers::Jump doneAdjusting = m_jit.jump();
fewFails.link(&m_jit);
lowFailRate.link(&m_jit);
- m_jit.store32(AssemblyHelpers::Imm32(m_jit.baselineCodeBlock()->counterValueForOptimizeAfterLongWarmUp()), AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfJITExecuteCounter()));
+ // Adjust the execution counter such that the target is to only optimize after a while.
+ int32_t targetValue =
+ ExecutionCounter::applyMemoryUsageHeuristicsAndConvertToInt(
+ m_jit.baselineCodeBlock()->counterValueForOptimizeAfterLongWarmUp(),
+ m_jit.baselineCodeBlock());
+ m_jit.store32(AssemblyHelpers::TrustedImm32(-targetValue), AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfJITExecuteCounter()));
+ m_jit.store32(AssemblyHelpers::TrustedImm32(targetValue), AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfJITExecutionActiveThreshold()));
+ m_jit.store32(AssemblyHelpers::TrustedImm32(ExecutionCounter::formattedTotalCount(targetValue)), AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfJITExecutionTotalCount()));
doneAdjusting.link(&m_jit);
@@ -618,24 +626,24 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, SpeculationRecovery* reco
GPRReg callerFrameGPR;
if (inlineCallFrame->caller.inlineCallFrame) {
- m_jit.add32(AssemblyHelpers::Imm32(inlineCallFrame->caller.inlineCallFrame->stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister, GPRInfo::regT3);
+ m_jit.add32(AssemblyHelpers::TrustedImm32(inlineCallFrame->caller.inlineCallFrame->stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister, GPRInfo::regT3);
callerFrameGPR = GPRInfo::regT3;
} else
callerFrameGPR = GPRInfo::callFrameRegister;
m_jit.storePtr(AssemblyHelpers::TrustedImmPtr(baselineCodeBlock), AssemblyHelpers::addressFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::CodeBlock)));
- m_jit.store32(AssemblyHelpers::Imm32(JSValue::CellTag), AssemblyHelpers::tagFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::ScopeChain)));
+ m_jit.store32(AssemblyHelpers::TrustedImm32(JSValue::CellTag), AssemblyHelpers::tagFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::ScopeChain)));
m_jit.storePtr(AssemblyHelpers::TrustedImmPtr(inlineCallFrame->callee->scope()), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::ScopeChain)));
- m_jit.store32(AssemblyHelpers::Imm32(JSValue::CellTag), AssemblyHelpers::tagFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::CallerFrame)));
+ m_jit.store32(AssemblyHelpers::TrustedImm32(JSValue::CellTag), AssemblyHelpers::tagFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::CallerFrame)));
m_jit.storePtr(callerFrameGPR, AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::CallerFrame)));
m_jit.storePtr(AssemblyHelpers::TrustedImmPtr(jumpTarget), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::ReturnPC)));
- m_jit.store32(AssemblyHelpers::Imm32(inlineCallFrame->arguments.size()), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::ArgumentCount)));
- m_jit.store32(AssemblyHelpers::Imm32(JSValue::CellTag), AssemblyHelpers::tagFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::Callee)));
+ m_jit.store32(AssemblyHelpers::TrustedImm32(inlineCallFrame->arguments.size()), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::ArgumentCount)));
+ m_jit.store32(AssemblyHelpers::TrustedImm32(JSValue::CellTag), AssemblyHelpers::tagFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::Callee)));
m_jit.storePtr(AssemblyHelpers::TrustedImmPtr(inlineCallFrame->callee.get()), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::Callee)));
}
if (exit.m_codeOrigin.inlineCallFrame)
- m_jit.addPtr(AssemblyHelpers::Imm32(exit.m_codeOrigin.inlineCallFrame->stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister);
+ m_jit.addPtr(AssemblyHelpers::TrustedImm32(exit.m_codeOrigin.inlineCallFrame->stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister);
// 14) Jump into the corresponding baseline JIT code.
diff --git a/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp b/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp
index f5e03973c..91a515c48 100644
--- a/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp
@@ -227,7 +227,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, SpeculationRecovery* reco
break;
case AlreadyInRegisterFileAsUnboxedInt32:
- m_jit.store32(AssemblyHelpers::Imm32(static_cast<uint32_t>(TagTypeNumber >> 32)), AssemblyHelpers::tagFor(static_cast<VirtualRegister>(exit.operandForIndex(index))));
+ m_jit.store32(AssemblyHelpers::TrustedImm32(static_cast<uint32_t>(TagTypeNumber >> 32)), AssemblyHelpers::tagFor(static_cast<VirtualRegister>(exit.operandForIndex(index))));
break;
case UInt32InGPR: {
@@ -541,32 +541,40 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, SpeculationRecovery* reco
// counter to 0; otherwise we set the counter to
// counterValueForOptimizeAfterWarmUp().
- m_jit.add32(AssemblyHelpers::Imm32(1), AssemblyHelpers::AbsoluteAddress(&exit.m_count));
+ m_jit.add32(AssemblyHelpers::TrustedImm32(1), AssemblyHelpers::AbsoluteAddress(&exit.m_count));
m_jit.move(AssemblyHelpers::TrustedImmPtr(m_jit.codeBlock()), GPRInfo::regT0);
m_jit.load32(AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfSpeculativeFailCounter()), GPRInfo::regT2);
m_jit.load32(AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfSpeculativeSuccessCounter()), GPRInfo::regT1);
- m_jit.add32(AssemblyHelpers::Imm32(1), GPRInfo::regT2);
- m_jit.add32(AssemblyHelpers::Imm32(-1), GPRInfo::regT1);
+ m_jit.add32(AssemblyHelpers::TrustedImm32(1), GPRInfo::regT2);
+ m_jit.add32(AssemblyHelpers::TrustedImm32(-1), GPRInfo::regT1);
m_jit.store32(GPRInfo::regT2, AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfSpeculativeFailCounter()));
m_jit.store32(GPRInfo::regT1, AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfSpeculativeSuccessCounter()));
m_jit.move(AssemblyHelpers::TrustedImmPtr(m_jit.baselineCodeBlock()), GPRInfo::regT0);
- AssemblyHelpers::Jump fewFails = m_jit.branch32(AssemblyHelpers::BelowOrEqual, GPRInfo::regT2, AssemblyHelpers::Imm32(m_jit.codeBlock()->largeFailCountThreshold()));
- m_jit.mul32(AssemblyHelpers::Imm32(Options::desiredSpeculativeSuccessFailRatio), GPRInfo::regT2, GPRInfo::regT2);
+ AssemblyHelpers::Jump fewFails = m_jit.branch32(AssemblyHelpers::BelowOrEqual, GPRInfo::regT2, AssemblyHelpers::TrustedImm32(m_jit.codeBlock()->largeFailCountThreshold()));
+ m_jit.mul32(AssemblyHelpers::TrustedImm32(Options::desiredSpeculativeSuccessFailRatio), GPRInfo::regT2, GPRInfo::regT2);
AssemblyHelpers::Jump lowFailRate = m_jit.branch32(AssemblyHelpers::BelowOrEqual, GPRInfo::regT2, GPRInfo::regT1);
// Reoptimize as soon as possible.
- m_jit.store32(AssemblyHelpers::Imm32(Options::executionCounterValueForOptimizeNextInvocation), AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfJITExecuteCounter()));
+ m_jit.store32(AssemblyHelpers::TrustedImm32(0), AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfJITExecuteCounter()));
+ m_jit.store32(AssemblyHelpers::TrustedImm32(0), AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfJITExecutionActiveThreshold()));
AssemblyHelpers::Jump doneAdjusting = m_jit.jump();
fewFails.link(&m_jit);
lowFailRate.link(&m_jit);
- m_jit.store32(AssemblyHelpers::Imm32(m_jit.baselineCodeBlock()->counterValueForOptimizeAfterLongWarmUp()), AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfJITExecuteCounter()));
+ // Adjust the execution counter such that the target is to only optimize after a while.
+ int32_t targetValue =
+ ExecutionCounter::applyMemoryUsageHeuristicsAndConvertToInt(
+ m_jit.baselineCodeBlock()->counterValueForOptimizeAfterLongWarmUp(),
+ m_jit.baselineCodeBlock());
+ m_jit.store32(AssemblyHelpers::TrustedImm32(-targetValue), AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfJITExecuteCounter()));
+ m_jit.store32(AssemblyHelpers::TrustedImm32(targetValue), AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfJITExecutionActiveThreshold()));
+ m_jit.store32(AssemblyHelpers::TrustedImm32(ExecutionCounter::formattedTotalCount(targetValue)), AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfJITExecutionTotalCount()));
doneAdjusting.link(&m_jit);
@@ -595,7 +603,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, SpeculationRecovery* reco
GPRReg callerFrameGPR;
if (inlineCallFrame->caller.inlineCallFrame) {
- m_jit.addPtr(AssemblyHelpers::Imm32(inlineCallFrame->caller.inlineCallFrame->stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister, GPRInfo::regT3);
+ m_jit.addPtr(AssemblyHelpers::TrustedImm32(inlineCallFrame->caller.inlineCallFrame->stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister, GPRInfo::regT3);
callerFrameGPR = GPRInfo::regT3;
} else
callerFrameGPR = GPRInfo::callFrameRegister;
@@ -609,7 +617,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, SpeculationRecovery* reco
}
if (exit.m_codeOrigin.inlineCallFrame)
- m_jit.addPtr(AssemblyHelpers::Imm32(exit.m_codeOrigin.inlineCallFrame->stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister);
+ m_jit.addPtr(AssemblyHelpers::TrustedImm32(exit.m_codeOrigin.inlineCallFrame->stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister);
// 16) Jump into the corresponding baseline JIT code.
diff --git a/Source/JavaScriptCore/dfg/DFGOperations.cpp b/Source/JavaScriptCore/dfg/DFGOperations.cpp
index 165a21416..304c54d95 100644
--- a/Source/JavaScriptCore/dfg/DFGOperations.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOperations.cpp
@@ -31,10 +31,12 @@
#include "DFGRepatch.h"
#include "HostCallReturnValue.h"
#include "GetterSetter.h"
-#include "InlineASM.h"
+#include <wtf/InlineASM.h>
#include "Interpreter.h"
+#include "JSActivation.h"
#include "JSByteArray.h"
#include "JSGlobalData.h"
+#include "JSStaticScopeObject.h"
#include "Operations.h"
#if ENABLE(DFG_JIT)
@@ -144,6 +146,7 @@ FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function)
namespace JSC { namespace DFG {
+template<bool strict>
static inline void putByVal(ExecState* exec, JSValue baseValue, uint32_t index, JSValue value)
{
JSGlobalData* globalData = &exec->globalData();
@@ -155,7 +158,7 @@ static inline void putByVal(ExecState* exec, JSValue baseValue, uint32_t index,
return;
}
- JSArray::putByIndex(array, exec, index, value);
+ JSArray::putByIndex(array, exec, index, value, strict);
return;
}
@@ -173,7 +176,7 @@ static inline void putByVal(ExecState* exec, JSValue baseValue, uint32_t index,
}
}
- baseValue.put(exec, index, value);
+ baseValue.putByIndex(exec, index, value, strict);
}
template<bool strict>
@@ -187,7 +190,7 @@ ALWAYS_INLINE static void DFG_OPERATION operationPutByValInternal(ExecState* exe
JSValue value = JSValue::decode(encodedValue);
if (LIKELY(property.isUInt32())) {
- putByVal(exec, baseValue, property.asUInt32(), value);
+ putByVal<strict>(exec, baseValue, property.asUInt32(), value);
return;
}
@@ -195,7 +198,7 @@ ALWAYS_INLINE static void DFG_OPERATION operationPutByValInternal(ExecState* exe
double propertyAsDouble = property.asDouble();
uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
if (propertyAsDouble == propertyAsUInt32) {
- putByVal(exec, baseValue, propertyAsUInt32, value);
+ putByVal<strict>(exec, baseValue, propertyAsUInt32, value);
return;
}
}
@@ -471,14 +474,24 @@ void DFG_OPERATION operationPutByValCellNonStrict(ExecState* exec, JSCell* cell,
operationPutByValInternal<false>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
}
-void DFG_OPERATION operationPutByValBeyondArrayBounds(ExecState* exec, JSArray* array, int32_t index, EncodedJSValue encodedValue)
+void DFG_OPERATION operationPutByValBeyondArrayBoundsStrict(ExecState* exec, JSArray* array, int32_t index, EncodedJSValue encodedValue)
+{
+ JSGlobalData* globalData = &exec->globalData();
+ NativeCallFrameTracer tracer(globalData, exec);
+
+ // We should only get here if index is outside the existing vector.
+ ASSERT(!array->canSetIndex(index));
+ JSArray::putByIndex(array, exec, index, JSValue::decode(encodedValue), true);
+}
+
+void DFG_OPERATION operationPutByValBeyondArrayBoundsNonStrict(ExecState* exec, JSArray* array, int32_t index, EncodedJSValue encodedValue)
{
JSGlobalData* globalData = &exec->globalData();
NativeCallFrameTracer tracer(globalData, exec);
// We should only get here if index is outside the existing vector.
ASSERT(!array->canSetIndex(index));
- JSArray::putByIndex(array, exec, index, JSValue::decode(encodedValue));
+ JSArray::putByIndex(array, exec, index, JSValue::decode(encodedValue), false);
}
EncodedJSValue DFG_OPERATION operationArrayPush(ExecState* exec, EncodedJSValue encodedValue, JSArray* array)
@@ -734,8 +747,11 @@ size_t DFG_OPERATION operationCompareStrictEq(ExecState* exec, EncodedJSValue en
{
JSGlobalData* globalData = &exec->globalData();
NativeCallFrameTracer tracer(globalData, exec);
+
+ JSValue src1 = JSValue::decode(encodedOp1);
+ JSValue src2 = JSValue::decode(encodedOp2);
- return JSValue::strictEqual(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
+ return JSValue::strictEqual(exec, src1, src2);
}
static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializationKind kind)
@@ -974,6 +990,43 @@ EncodedJSValue DFG_OPERATION operationNewRegexp(ExecState* exec, void* regexpPtr
return JSValue::encode(RegExpObject::create(exec->globalData(), exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->regExpStructure(), regexp));
}
+JSCell* DFG_OPERATION operationCreateActivation(ExecState* exec)
+{
+ JSGlobalData& globalData = exec->globalData();
+ JSActivation* activation = JSActivation::create(
+ globalData, exec, static_cast<FunctionExecutable*>(exec->codeBlock()->ownerExecutable()));
+ exec->setScopeChain(exec->scopeChain()->push(activation));
+ return activation;
+}
+
+void DFG_OPERATION operationTearOffActivation(ExecState* exec, JSCell* activation)
+{
+ ASSERT(activation);
+ ASSERT(activation->inherits(&JSActivation::s_info));
+ static_cast<JSActivation*>(activation)->tearOff(exec->globalData());
+}
+
+JSCell* DFG_OPERATION operationNewFunction(ExecState* exec, JSCell* functionExecutable)
+{
+ ASSERT(functionExecutable->inherits(&FunctionExecutable::s_info));
+ return static_cast<FunctionExecutable*>(functionExecutable)->make(exec, exec->scopeChain());
+}
+
+JSCell* DFG_OPERATION operationNewFunctionExpression(ExecState* exec, JSCell* functionExecutableAsCell)
+{
+ ASSERT(functionExecutableAsCell->inherits(&FunctionExecutable::s_info));
+ FunctionExecutable* functionExecutable =
+ static_cast<FunctionExecutable*>(functionExecutableAsCell);
+ JSFunction *function = functionExecutable->make(exec, exec->scopeChain());
+ if (!functionExecutable->name().isNull()) {
+ JSStaticScopeObject* functionScopeObject =
+ JSStaticScopeObject::create(
+ exec, functionExecutable->name(), function, ReadOnly | DontDelete);
+ function->setScope(exec->globalData(), function->scope()->push(functionScopeObject));
+ }
+ return function;
+}
+
DFGHandlerEncoded DFG_OPERATION lookupExceptionHandler(ExecState* exec, uint32_t callIndex)
{
JSGlobalData* globalData = &exec->globalData();
diff --git a/Source/JavaScriptCore/dfg/DFGOperations.h b/Source/JavaScriptCore/dfg/DFGOperations.h
index cdb88de27..4ca58d621 100644
--- a/Source/JavaScriptCore/dfg/DFGOperations.h
+++ b/Source/JavaScriptCore/dfg/DFGOperations.h
@@ -89,6 +89,7 @@ typedef void DFG_OPERATION (*V_DFGOperation_EAZJ)(ExecState*, JSArray*, int32_t,
typedef double DFG_OPERATION (*D_DFGOperation_DD)(double, double);
typedef double DFG_OPERATION (*D_DFGOperation_EJ)(ExecState*, EncodedJSValue);
typedef void* DFG_OPERATION (*P_DFGOperation_E)(ExecState*);
+typedef void DFG_OPERATION (V_DFGOperation_EC)(ExecState*, JSCell*);
// These routines are provide callbacks out to C++ implementations of operations too complex to JIT.
JSCell* DFG_OPERATION operationNewObject(ExecState*);
@@ -118,7 +119,8 @@ void DFG_OPERATION operationPutByValStrict(ExecState*, EncodedJSValue encodedBas
void DFG_OPERATION operationPutByValNonStrict(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue);
void DFG_OPERATION operationPutByValCellStrict(ExecState*, JSCell*, EncodedJSValue encodedProperty, EncodedJSValue encodedValue);
void DFG_OPERATION operationPutByValCellNonStrict(ExecState*, JSCell*, EncodedJSValue encodedProperty, EncodedJSValue encodedValue);
-void DFG_OPERATION operationPutByValBeyondArrayBounds(ExecState*, JSArray*, int32_t index, EncodedJSValue encodedValue);
+void DFG_OPERATION operationPutByValBeyondArrayBoundsStrict(ExecState*, JSArray*, int32_t index, EncodedJSValue encodedValue);
+void DFG_OPERATION operationPutByValBeyondArrayBoundsNonStrict(ExecState*, JSArray*, int32_t index, EncodedJSValue encodedValue);
EncodedJSValue DFG_OPERATION operationArrayPush(ExecState*, EncodedJSValue encodedValue, JSArray*);
EncodedJSValue DFG_OPERATION operationArrayPop(ExecState*, JSArray*);
void DFG_OPERATION operationPutByIdStrict(ExecState*, EncodedJSValue encodedValue, JSCell* base, Identifier*);
@@ -145,6 +147,10 @@ void* DFG_OPERATION operationVirtualCall(ExecState*);
void* DFG_OPERATION operationLinkCall(ExecState*);
void* DFG_OPERATION operationVirtualConstruct(ExecState*);
void* DFG_OPERATION operationLinkConstruct(ExecState*);
+JSCell* DFG_OPERATION operationCreateActivation(ExecState*);
+void DFG_OPERATION operationTearOffActivation(ExecState*, JSCell*);
+JSCell* DFG_OPERATION operationNewFunction(ExecState*, JSCell*);
+JSCell* DFG_OPERATION operationNewFunctionExpression(ExecState*, JSCell*);
// 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.
diff --git a/Source/JavaScriptCore/dfg/DFGPhase.cpp b/Source/JavaScriptCore/dfg/DFGPhase.cpp
index bc1eabff4..bae12b1cc 100644
--- a/Source/JavaScriptCore/dfg/DFGPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGPhase.cpp
@@ -35,7 +35,7 @@ void Phase::beginPhase()
{
dataLog("Beginning DFG phase %s.\n", m_name);
dataLog("Graph before %s:\n", m_name);
- m_graph.dump(m_codeBlock);
+ m_graph.dump();
}
void Phase::endPhase()
diff --git a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
index b4c9e075a..98bdaac06 100644
--- a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
@@ -105,7 +105,7 @@ private:
if (!node.shouldGenerate())
return;
- NodeType op = node.op;
+ NodeType op = static_cast<NodeType>(node.op);
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLog(" %s @%u: ", Graph::opName(op), m_compileIndex);
@@ -209,6 +209,15 @@ private:
break;
}
+ case ArithNegate:
+ if (m_graph[node.child1()].prediction()) {
+ if (m_graph.negateShouldSpeculateInteger(node))
+ changed |= mergePrediction(PredictInt32);
+ else
+ changed |= mergePrediction(PredictDouble);
+ }
+ break;
+
case ArithMul:
case ArithMin:
case ArithMax:
@@ -397,6 +406,18 @@ private:
break;
}
+ case CreateActivation: {
+ changed |= setPrediction(PredictObjectOther);
+ break;
+ }
+
+ case NewFunction:
+ case NewFunctionNoCheck:
+ case NewFunctionExpression: {
+ changed |= setPrediction(PredictFunction);
+ break;
+ }
+
case GetArrayLength:
case GetByteArrayLength:
case GetInt8ArrayLength:
@@ -415,6 +436,9 @@ private:
break;
}
+ case Flush:
+ break;
+
#ifndef NDEBUG
// These get ignored because they don't return anything.
case PutScopedVar:
@@ -424,7 +448,6 @@ private:
case Return:
case CheckHasInstance:
case Phi:
- case Flush:
case Throw:
case ThrowReferenceError:
case ForceOSRExit:
@@ -437,6 +460,7 @@ private:
case CheckFunction:
case PutStructure:
case PutByOffset:
+ case TearOffActivation:
break;
// These gets ignored because it doesn't do anything.
@@ -444,6 +468,10 @@ private:
case InlineStart:
case Nop:
break;
+
+ case LastNodeType:
+ ASSERT_NOT_REACHED();
+ break;
#else
default:
break;
@@ -492,7 +520,7 @@ private:
void vote(Node& node, VariableAccessData::Ballot ballot)
{
- if (node.op & NodeHasVarArgs) {
+ if (node.flags & NodeHasVarArgs) {
for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); childIdx++)
vote(m_graph.m_varArgChildren[childIdx], ballot);
return;
@@ -586,8 +614,13 @@ private:
break;
}
}
- for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i)
- m_changed |= m_graph.m_variableAccessData[i].find()->tallyVotesForShouldUseDoubleFormat();
+ for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) {
+ VariableAccessData* variableAccessData = m_graph.m_variableAccessData[i].find();
+ if (operandIsArgument(variableAccessData->local())
+ || m_graph.isCaptured(variableAccessData->local()))
+ continue;
+ m_changed |= variableAccessData->tallyVotesForShouldUseDoubleFormat();
+ }
}
void fixupNode(Node& node)
@@ -595,7 +628,7 @@ private:
if (!node.shouldGenerate())
return;
- NodeType op = node.op;
+ NodeType op = static_cast<NodeType>(node.op);
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLog(" %s @%u: ", Graph::opName(op), m_compileIndex);
@@ -651,13 +684,16 @@ private:
node.op = GetFloat64ArrayLength;
else
ASSERT_NOT_REACHED();
- m_graph.deref(m_compileIndex); // No longer MustGenerate
+ // No longer MustGenerate
+ ASSERT(node.flags & NodeMustGenerate);
+ node.flags &= ~NodeMustGenerate;
+ m_graph.deref(m_compileIndex);
break;
}
case GetIndexedPropertyStorage: {
PredictedType basePrediction = m_graph[node.child2()].prediction();
if (!(basePrediction & PredictInt32) && basePrediction) {
- node.op = Nop;
+ node.setOpAndDefaultFlags(Nop);
m_graph.clearAndDerefChild1(node);
m_graph.clearAndDerefChild2(node);
m_graph.clearAndDerefChild3(node);
diff --git a/Source/JavaScriptCore/dfg/DFGRedundantPhiEliminationPhase.cpp b/Source/JavaScriptCore/dfg/DFGRedundantPhiEliminationPhase.cpp
new file mode 100644
index 000000000..fb30de742
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGRedundantPhiEliminationPhase.cpp
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 "DFGRedundantPhiEliminationPhase.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGGraph.h"
+
+namespace JSC { namespace DFG {
+
+class RedundantPhiEliminationPhase : public Phase {
+public:
+ RedundantPhiEliminationPhase(Graph& graph)
+ : Phase(graph, "redundant phi elimination")
+ {
+ }
+
+ void run()
+ {
+ bool changed = false;
+ do {
+ changed = fixupPhis();
+ } while (changed);
+
+ updateBlockVariableInformation();
+
+ // Update the Phi references from non-Phi nodes, e.g., the GetLocals.
+ for (NodeIndex index = 0; index < m_graph.size(); ++index) {
+ Node& node = m_graph[index];
+
+ if (!node.shouldGenerate())
+ continue;
+
+ switch (node.op) {
+ case GetLocal:
+ replacePhiChild(node, 0);
+ break;
+ default:
+ break;
+ }
+ }
+
+ }
+
+private:
+ NodeIndex getRedundantReplacement(NodeIndex phi)
+ {
+ NodeIndex child1 = m_graph[phi].child1().indexUnchecked();
+ NodeIndex candidate = child1 == phi ? NoNode : child1;
+
+ NodeIndex child2 = m_graph[phi].child2().indexUnchecked();
+ if (candidate != NoNode) {
+ if (child2 != NoNode && child2 != candidate && child2 != phi)
+ return NoNode;
+ } else if (child2 != phi)
+ candidate = child2;
+
+ NodeIndex child3 = m_graph[phi].child3().indexUnchecked();
+ if (candidate != NoNode) {
+ if (child3 != NoNode && child3 != candidate && child3 != phi)
+ return NoNode;
+ } else if (child3 != phi)
+ candidate = child3;
+
+ return candidate;
+ }
+
+ bool replacePhiChild(Node& node, unsigned childIndex)
+ {
+ ASSERT(childIndex < 3);
+
+ bool replaced = false;
+ NodeIndex child = node.children.child(childIndex).indexUnchecked();
+ if (child != NoNode && m_graph[child].op == Phi) {
+ NodeIndex childReplacement = getRedundantReplacement(child);
+ if (childReplacement != NoNode) {
+ node.children.child(childIndex).setIndex(childReplacement);
+ replaced = true;
+ if (node.refCount()) {
+ m_graph[childReplacement].ref();
+ m_graph.deref(child);
+ }
+ }
+ }
+ return replaced;
+ }
+
+ bool fixupPhis()
+ {
+ bool changed = false;
+
+ for (BlockIndex block = 0; block < m_graph.m_blocks.size(); ++block) {
+ Vector<NodeIndex>& phis = m_graph.m_blocks[block]->phis;
+
+ for (size_t i = 0; i < phis.size(); ++i) {
+ NodeIndex phi = phis[i];
+ Node& phiNode = m_graph[phi];
+
+ changed |= (replacePhiChild(phiNode, 0) && phiNode.refCount());
+ changed |= (replacePhiChild(phiNode, 1) && phiNode.refCount());
+ changed |= (replacePhiChild(phiNode, 2) && phiNode.refCount());
+ }
+ }
+
+ return changed;
+ }
+
+ void updateBlockVariableInformation()
+ {
+ // Redundant Phi nodes are eliminated, we need to update
+ // the variable information if it references them.
+ for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
+ BasicBlock* basicBlock = m_graph.m_blocks[blockIndex].get();
+
+ for (size_t arg = 0; arg < basicBlock->variablesAtHead.numberOfArguments(); ++arg) {
+ NodeIndex nodeIndex = basicBlock->variablesAtHead.argument(arg);
+ if (nodeIndex != NoNode && m_graph[nodeIndex].op == Phi && !m_graph[nodeIndex].refCount()) {
+ NodeIndex replacement = getRedundantReplacement(nodeIndex);
+ if (replacement != NoNode) {
+ // This argument must be unused in this block.
+ ASSERT(basicBlock->variablesAtTail.argument(arg) == nodeIndex);
+ basicBlock->variablesAtHead.argument(arg) = replacement;
+ basicBlock->variablesAtTail.argument(arg) = replacement;
+ }
+ }
+ }
+
+ for (size_t local = 0; local < basicBlock->variablesAtHead.numberOfLocals(); ++local) {
+ NodeIndex nodeIndex = basicBlock->variablesAtHead.local(local);
+ if (nodeIndex != NoNode && m_graph[nodeIndex].op == Phi && !m_graph[nodeIndex].refCount()) {
+ NodeIndex replacement = getRedundantReplacement(nodeIndex);
+ if (replacement != NoNode) {
+ // This local variable must be unused in this block.
+ ASSERT(basicBlock->variablesAtTail.local(local) == nodeIndex);
+ basicBlock->variablesAtHead.local(local) = replacement;
+ basicBlock->variablesAtTail.local(local) = replacement;
+ }
+ }
+ }
+ }
+ }
+
+};
+
+void performRedundantPhiElimination(Graph& graph)
+{
+ runPhase<RedundantPhiEliminationPhase>(graph);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
diff --git a/Source/JavaScriptCore/dfg/DFGRedundantPhiEliminationPhase.h b/Source/JavaScriptCore/dfg/DFGRedundantPhiEliminationPhase.h
new file mode 100644
index 000000000..202ab4441
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGRedundantPhiEliminationPhase.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 DFGRedundantPhiEliminationPhase_h
+#define DFGRedundantPhiEliminationPhase_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGPhase.h"
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+// We inserted many can-be-redundant Phi nodes when building the graph.
+// This phase will just remove them.
+
+void performRedundantPhiElimination(Graph&);
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGRedundantPhiEliminationPhase_h
+
diff --git a/Source/JavaScriptCore/dfg/DFGScoreBoard.h b/Source/JavaScriptCore/dfg/DFGScoreBoard.h
index 912b3e8fd..140de185b 100644
--- a/Source/JavaScriptCore/dfg/DFGScoreBoard.h
+++ b/Source/JavaScriptCore/dfg/DFGScoreBoard.h
@@ -58,14 +58,27 @@ public:
}
}
-#if DFG_ENABLE(CONSISTENCY_CHECK)
~ScoreBoard()
{
- // For every entry in the used list the use count of the virtual register should be zero.
- for (size_t i = 0; i < m_free.size(); ++i)
- ASSERT(!m_used[i] || m_used[i] == max());
+ assertClear();
}
+
+ void assertClear()
+ {
+#if !ASSERT_DISABLED
+ // 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());
+ // 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]]);
+ // 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]);
+ }
#endif
+ }
VirtualRegister allocate()
{
@@ -99,6 +112,9 @@ public:
uint32_t index = node.virtualRegister();
ASSERT(m_used[index] != max());
if (node.refCount() == ++m_used[index]) {
+#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
+ dataLog(" Freeing virtual register %u.", index);
+#endif
// If the use count in the scoreboard reaches the use count for the node,
// then this was its last use; the virtual register is now free.
// Clear the use count & add to the free list.
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
index 8578337f5..7bcb44576 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
@@ -83,7 +83,7 @@ GPRReg SpeculativeJIT::fillStorage(NodeIndex nodeIndex)
void SpeculativeJIT::useChildren(Node& node)
{
- if (node.op & NodeHasVarArgs) {
+ if (node.flags & NodeHasVarArgs) {
for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); childIdx++)
use(m_jit.graph().m_varArgChildren[childIdx]);
} else {
@@ -365,12 +365,15 @@ void SpeculativeJIT::writeBarrier(JSCell* owner, GPRReg valueGPR, NodeUse valueU
bool SpeculativeJIT::nonSpeculativeCompare(Node& node, MacroAssembler::RelationalCondition cond, S_DFGOperation_EJJ helperFunction)
{
- NodeIndex branchNodeIndex = detectPeepHoleBranch();
- if (branchNodeIndex != NoNode) {
+ unsigned branchIndexInBlock = detectPeepHoleBranch();
+ if (branchIndexInBlock != UINT_MAX) {
+ NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
+
ASSERT(node.adjustedRefCount() == 1);
nonSpeculativePeepholeBranch(node, branchNodeIndex, cond, helperFunction);
+ m_indexInBlock = branchIndexInBlock;
m_compileIndex = branchNodeIndex;
return true;
@@ -383,15 +386,15 @@ bool SpeculativeJIT::nonSpeculativeCompare(Node& node, MacroAssembler::Relationa
bool SpeculativeJIT::nonSpeculativeStrictEq(Node& node, bool invert)
{
- if (!invert && (isKnownNumeric(node.child1().index()) || isKnownNumeric(node.child2().index())))
- return nonSpeculativeCompare(node, MacroAssembler::Equal, operationCompareStrictEq);
-
- NodeIndex branchNodeIndex = detectPeepHoleBranch();
- if (branchNodeIndex != NoNode) {
+ unsigned branchIndexInBlock = detectPeepHoleBranch();
+ if (branchIndexInBlock != UINT_MAX) {
+ NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
+
ASSERT(node.adjustedRefCount() == 1);
nonSpeculativePeepholeStrictEq(node, branchNodeIndex, invert);
+ m_indexInBlock = branchIndexInBlock;
m_compileIndex = branchNodeIndex;
return true;
@@ -765,7 +768,6 @@ FPRTemporary::FPRTemporary(SpeculativeJIT* jit, JSValueOperand& op1)
}
#endif
-#ifndef NDEBUG
void ValueSource::dump(FILE* out) const
{
switch (kind()) {
@@ -792,7 +794,6 @@ void ValueSource::dump(FILE* out) const
break;
}
}
-#endif
void SpeculativeJIT::compilePeepHoleDoubleBranch(Node& node, NodeIndex branchNodeIndex, JITCompiler::DoubleCondition condition)
{
@@ -873,8 +874,10 @@ void SpeculativeJIT::compilePeepHoleIntegerBranch(Node& node, NodeIndex branchNo
bool SpeculativeJIT::compilePeepHoleBranch(Node& node, MacroAssembler::RelationalCondition condition, MacroAssembler::DoubleCondition doubleCondition, S_DFGOperation_EJJ operation)
{
// Fused compare & branch.
- NodeIndex branchNodeIndex = detectPeepHoleBranch();
- if (branchNodeIndex != NoNode) {
+ unsigned branchIndexInBlock = detectPeepHoleBranch();
+ if (branchIndexInBlock != UINT_MAX) {
+ NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
+
// detectPeepHoleBranch currently only permits the branch to be the very next node,
// so can be no intervening nodes to also reference the compare.
ASSERT(node.adjustedRefCount() == 1);
@@ -898,6 +901,7 @@ bool SpeculativeJIT::compilePeepHoleBranch(Node& node, MacroAssembler::Relationa
} else
nonSpeculativePeepholeBranch(node, branchNodeIndex, condition, operation);
+ m_indexInBlock = branchIndexInBlock;
m_compileIndex = branchNodeIndex;
return true;
}
@@ -915,12 +919,9 @@ void SpeculativeJIT::compileMovHint(Node& node)
void SpeculativeJIT::compile(BasicBlock& block)
{
ASSERT(m_compileOkay);
- ASSERT(m_compileIndex == block.begin);
- if (!block.isReachable) {
- m_compileIndex = block.end;
+ if (!block.isReachable)
return;
- }
m_blockHeads[m_block] = m_jit.label();
#if DFG_ENABLE(JIT_BREAK_ON_EVERY_BLOCK)
@@ -930,7 +931,7 @@ void SpeculativeJIT::compile(BasicBlock& block)
ASSERT(m_arguments.size() == block.variablesAtHead.numberOfArguments());
for (size_t i = 0; i < m_arguments.size(); ++i) {
NodeIndex nodeIndex = block.variablesAtHead.argument(i);
- if (nodeIndex == NoNode)
+ if (nodeIndex == NoNode || m_jit.graph().argumentIsCaptured(i))
m_arguments[i] = ValueSource(ValueInRegisterFile);
else
m_arguments[i] = ValueSource::forPrediction(at(nodeIndex).variableAccessData()->prediction());
@@ -942,7 +943,7 @@ void SpeculativeJIT::compile(BasicBlock& block)
ASSERT(m_variables.size() == block.variablesAtHead.numberOfLocals());
for (size_t i = 0; i < m_variables.size(); ++i) {
NodeIndex nodeIndex = block.variablesAtHead.local(i);
- if (nodeIndex == NoNode)
+ if (nodeIndex == NoNode || m_jit.graph().localIsCaptured(i))
m_variables[i] = ValueSource(ValueInRegisterFile);
else if (at(nodeIndex).variableAccessData()->shouldUseDoubleFormat())
m_variables[i] = ValueSource(DoubleInRegisterFile);
@@ -955,12 +956,13 @@ void SpeculativeJIT::compile(BasicBlock& block)
if (DFG_ENABLE_EDGE_CODE_VERIFICATION) {
JITCompiler::Jump verificationSucceeded =
- m_jit.branch32(JITCompiler::Equal, GPRInfo::regT0, Imm32(m_block));
+ m_jit.branch32(JITCompiler::Equal, GPRInfo::regT0, TrustedImm32(m_block));
m_jit.breakpoint();
verificationSucceeded.link(&m_jit);
}
- for (; m_compileIndex < block.end; ++m_compileIndex) {
+ for (m_indexInBlock = 0; m_indexInBlock < block.size(); ++m_indexInBlock) {
+ m_compileIndex = block[m_indexInBlock];
Node& node = at(m_compileIndex);
m_codeOriginForOSR = node.codeOrigin;
if (!node.shouldGenerate()) {
@@ -1005,7 +1007,6 @@ void SpeculativeJIT::compile(BasicBlock& block)
compile(node);
if (!m_compileOkay) {
m_compileOkay = true;
- m_compileIndex = block.end;
clearGenerationInfo();
return;
}
@@ -1045,7 +1046,7 @@ void SpeculativeJIT::compile(BasicBlock& block)
#endif
// Make sure that the abstract state is rematerialized for the next node.
- m_state.execute(m_compileIndex);
+ m_state.execute(m_indexInBlock);
if (node.shouldGenerate())
checkConsistency();
@@ -1232,7 +1233,7 @@ bool SpeculativeJIT::compile()
checkArgumentTypes();
if (DFG_ENABLE_EDGE_CODE_VERIFICATION)
- m_jit.move(Imm32(0), GPRInfo::regT0);
+ m_jit.move(TrustedImm32(0), GPRInfo::regT0);
ASSERT(!m_compileIndex);
for (m_block = 0; m_block < m_jit.graph().m_blocks.size(); ++m_block)
@@ -1258,7 +1259,7 @@ void SpeculativeJIT::createOSREntries()
}
m_osrEntryHeads.append(m_jit.label());
- m_jit.move(Imm32(blockIndex), GPRInfo::regT0);
+ m_jit.move(TrustedImm32(blockIndex), GPRInfo::regT0);
m_jit.jump().linkTo(m_blockHeads[blockIndex], &m_jit);
}
}
@@ -2318,8 +2319,14 @@ void SpeculativeJIT::compileArithSub(Node& node)
if (nodeCanTruncateInteger(node.arithNodeFlags())) {
m_jit.move(op1.gpr(), result.gpr());
m_jit.sub32(Imm32(imm2), result.gpr());
- } else
+ } else {
+#if ENABLE(JIT_CONSTANT_BLINDING)
+ GPRTemporary scratch(this);
+ speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchSub32(MacroAssembler::Overflow, op1.gpr(), Imm32(imm2), result.gpr(), scratch.gpr()));
+#else
speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchSub32(MacroAssembler::Overflow, op1.gpr(), Imm32(imm2), result.gpr()));
+#endif
+ }
integerResult(result.gpr(), m_compileIndex);
return;
@@ -2365,6 +2372,34 @@ void SpeculativeJIT::compileArithSub(Node& node)
doubleResult(result.fpr(), m_compileIndex);
}
+void SpeculativeJIT::compileArithNegate(Node& node)
+{
+ if (m_jit.graph().negateShouldSpeculateInteger(node)) {
+ SpeculateIntegerOperand op1(this, node.child1());
+ GPRTemporary result(this);
+
+ m_jit.move(op1.gpr(), result.gpr());
+
+ if (nodeCanTruncateInteger(node.arithNodeFlags()))
+ m_jit.neg32(result.gpr());
+ else {
+ speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchNeg32(MacroAssembler::Overflow, result.gpr()));
+ if (!nodeCanIgnoreNegativeZero(node.arithNodeFlags()))
+ speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchTest32(MacroAssembler::Zero, result.gpr()));
+ }
+
+ integerResult(result.gpr(), m_compileIndex);
+ return;
+ }
+
+ SpeculateDoubleOperand op1(this, node.child1());
+ FPRTemporary result(this);
+
+ m_jit.negateDouble(op1.fpr(), result.fpr());
+
+ doubleResult(result.fpr(), m_compileIndex);
+}
+
void SpeculativeJIT::compileArithMul(Node& node)
{
if (Node::shouldSpeculateInteger(at(node.child1()), at(node.child2())) && node.canSpeculateInteger()) {
@@ -2456,8 +2491,9 @@ bool SpeculativeJIT::compileStrictEqForConstant(Node& node, NodeUse value, JSVal
{
JSValueOperand op1(this, value);
- NodeIndex branchNodeIndex = detectPeepHoleBranch();
- if (branchNodeIndex != NoNode) {
+ unsigned branchIndexInBlock = detectPeepHoleBranch();
+ if (branchIndexInBlock != UINT_MAX) {
+ NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
Node& branchNode = at(branchNodeIndex);
BlockIndex taken = branchNode.takenBlockIndex();
BlockIndex notTaken = branchNode.notTakenBlockIndex();
@@ -2493,6 +2529,7 @@ bool SpeculativeJIT::compileStrictEqForConstant(Node& node, NodeUse value, JSVal
use(node.child1());
use(node.child2());
+ m_indexInBlock = branchIndexInBlock;
m_compileIndex = branchNodeIndex;
return true;
}
@@ -2504,18 +2541,18 @@ bool SpeculativeJIT::compileStrictEqForConstant(Node& node, NodeUse value, JSVal
GPRReg resultGPR = result.gpr();
m_jit.move(MacroAssembler::TrustedImmPtr(bitwise_cast<void*>(ValueFalse)), resultGPR);
MacroAssembler::Jump notEqual = m_jit.branchPtr(MacroAssembler::NotEqual, op1GPR, MacroAssembler::TrustedImmPtr(bitwise_cast<void*>(JSValue::encode(constant))));
- m_jit.or32(MacroAssembler::Imm32(1), resultGPR);
+ m_jit.or32(MacroAssembler::TrustedImm32(1), resultGPR);
notEqual.link(&m_jit);
jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean);
#else
GPRReg op1PayloadGPR = op1.payloadGPR();
GPRReg op1TagGPR = op1.tagGPR();
GPRReg resultGPR = result.gpr();
- m_jit.move(Imm32(0), resultGPR);
+ m_jit.move(TrustedImm32(0), resultGPR);
MacroAssembler::JumpList notEqual;
notEqual.append(m_jit.branch32(MacroAssembler::NotEqual, op1TagGPR, MacroAssembler::Imm32(constant.tag())));
notEqual.append(m_jit.branch32(MacroAssembler::NotEqual, op1PayloadGPR, MacroAssembler::Imm32(constant.payload())));
- m_jit.move(Imm32(1), resultGPR);
+ m_jit.move(TrustedImm32(1), resultGPR);
notEqual.link(&m_jit);
booleanResult(resultGPR, m_compileIndex);
#endif
@@ -2543,11 +2580,13 @@ bool SpeculativeJIT::compileStrictEq(Node& node)
// 2) If the operands are predicted integer, do an integer comparison.
if (Node::shouldSpeculateInteger(at(node.child1()), at(node.child2()))) {
- NodeIndex branchNodeIndex = detectPeepHoleBranch();
- if (branchNodeIndex != NoNode) {
+ unsigned branchIndexInBlock = detectPeepHoleBranch();
+ if (branchIndexInBlock != UINT_MAX) {
+ NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
compilePeepHoleIntegerBranch(node, branchNodeIndex, MacroAssembler::Equal);
use(node.child1());
use(node.child2());
+ m_indexInBlock = branchIndexInBlock;
m_compileIndex = branchNodeIndex;
return true;
}
@@ -2558,11 +2597,13 @@ bool SpeculativeJIT::compileStrictEq(Node& node)
// 3) If the operands are predicted double, do a double comparison.
if (Node::shouldSpeculateNumber(at(node.child1()), at(node.child2()))) {
- NodeIndex branchNodeIndex = detectPeepHoleBranch();
- if (branchNodeIndex != NoNode) {
+ unsigned branchIndexInBlock = detectPeepHoleBranch();
+ if (branchIndexInBlock != UINT_MAX) {
+ NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
compilePeepHoleDoubleBranch(node, branchNodeIndex, MacroAssembler::DoubleEqual);
use(node.child1());
use(node.child2());
+ m_indexInBlock = branchIndexInBlock;
m_compileIndex = branchNodeIndex;
return true;
}
@@ -2574,11 +2615,13 @@ bool SpeculativeJIT::compileStrictEq(Node& node)
// or array comparison.
if (Node::shouldSpeculateFinalObject(at(node.child1()), at(node.child2()))) {
- NodeIndex branchNodeIndex = detectPeepHoleBranch();
- if (branchNodeIndex != NoNode) {
+ unsigned branchIndexInBlock = detectPeepHoleBranch();
+ if (branchIndexInBlock != UINT_MAX) {
+ NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
compilePeepHoleObjectEquality(node, branchNodeIndex, &JSFinalObject::s_info, isFinalObjectPrediction);
use(node.child1());
use(node.child2());
+ m_indexInBlock = branchIndexInBlock;
m_compileIndex = branchNodeIndex;
return true;
}
@@ -2587,11 +2630,13 @@ bool SpeculativeJIT::compileStrictEq(Node& node)
}
if (Node::shouldSpeculateArray(at(node.child1()), at(node.child2()))) {
- NodeIndex branchNodeIndex = detectPeepHoleBranch();
- if (branchNodeIndex != NoNode) {
+ unsigned branchIndexInBlock = detectPeepHoleBranch();
+ if (branchIndexInBlock != UINT_MAX) {
+ NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
compilePeepHoleObjectEquality(node, branchNodeIndex, &JSArray::s_info, isArrayPrediction);
use(node.child1());
use(node.child2());
+ m_indexInBlock = branchIndexInBlock;
m_compileIndex = branchNodeIndex;
return true;
}
@@ -2691,6 +2736,28 @@ void SpeculativeJIT::compileGetIndexedPropertyStorage(Node& node)
storageResult(storageReg, m_compileIndex);
}
+void SpeculativeJIT::compileNewFunctionNoCheck(Node& node)
+{
+ GPRResult result(this);
+ GPRReg resultGPR = result.gpr();
+ flushRegisters();
+ callOperation(
+ operationNewFunction, resultGPR, m_jit.codeBlock()->functionDecl(node.functionDeclIndex()));
+ cellResult(resultGPR, m_compileIndex);
+}
+
+void SpeculativeJIT::compileNewFunctionExpression(Node& node)
+{
+ GPRResult result(this);
+ GPRReg resultGPR = result.gpr();
+ flushRegisters();
+ callOperation(
+ operationNewFunctionExpression,
+ resultGPR,
+ m_jit.codeBlock()->functionExpr(node.functionExprIndex()));
+ cellResult(resultGPR, m_compileIndex);
+}
+
} } // namespace JSC::DFG
#endif
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
index 5d95b064f..1744a03f3 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
@@ -104,9 +104,7 @@ public:
return m_nodeIndex;
}
-#ifndef NDEBUG
void dump(FILE* out) const;
-#endif
private:
static NodeIndex nodeIndexFromKind(ValueSourceKind kind)
@@ -454,7 +452,7 @@ private:
ASSERT(info.gpr() == target);
if (node.hasConstant()) {
ASSERT(isBooleanConstant(nodeIndex));
- m_jit.move(Imm32(valueOfBooleanConstant(nodeIndex)), target);
+ m_jit.move(TrustedImm32(valueOfBooleanConstant(nodeIndex)), target);
} else
m_jit.load32(JITCompiler::payloadFor(spillMe), target);
#endif
@@ -466,7 +464,7 @@ private:
if (node.hasConstant()) {
JSValue value = valueOfJSConstant(nodeIndex);
ASSERT(value.isCell());
- m_jit.move(ImmPtr(value.asCell()), target);
+ m_jit.move(TrustedImmPtr(value.asCell()), target);
} else
m_jit.loadPtr(JITCompiler::payloadFor(spillMe), target);
return;
@@ -481,9 +479,12 @@ private:
ASSERT(registerFormat & DataFormatJS);
#if USE(JSVALUE64)
ASSERT(info.gpr() == target);
- if (node.hasConstant())
- m_jit.move(valueOfJSConstantAsImmPtr(nodeIndex), target);
- else if (info.spillFormat() == DataFormatInteger) {
+ if (node.hasConstant()) {
+ if (valueOfJSConstant(nodeIndex).isCell())
+ m_jit.move(valueOfJSConstantAsImmPtr(nodeIndex).asTrustedImmPtr(), target);
+ else
+ m_jit.move(valueOfJSConstantAsImmPtr(nodeIndex), target);
+ } else if (info.spillFormat() == DataFormatInteger) {
ASSERT(registerFormat == DataFormatJSInteger);
m_jit.load32(JITCompiler::payloadFor(spillMe), target);
m_jit.orPtr(GPRInfo::tagTypeNumberRegister, target);
@@ -875,20 +876,21 @@ private:
}
}
- // Returns the node index of the branch node if peephole is okay, NoNode otherwise.
- NodeIndex detectPeepHoleBranch()
+ // Returns the index of the branch node if peephole is okay, UINT_MAX otherwise.
+ unsigned detectPeepHoleBranch()
{
- NodeIndex lastNodeIndex = m_jit.graph().m_blocks[m_block]->end - 1;
+ BasicBlock* block = m_jit.graph().m_blocks[m_block].get();
// Check that no intervening nodes will be generated.
- for (NodeIndex index = m_compileIndex + 1; index < lastNodeIndex; ++index) {
- if (at(index).shouldGenerate())
- return NoNode;
+ for (unsigned index = m_indexInBlock + 1; index < block->size() - 1; ++index) {
+ NodeIndex nodeIndex = block->at(index);
+ if (at(nodeIndex).shouldGenerate())
+ return UINT_MAX;
}
// Check if the lastNode is a branch on this node.
- Node& lastNode = at(lastNodeIndex);
- return lastNode.op == Branch && lastNode.child1().index() == m_compileIndex ? lastNodeIndex : NoNode;
+ Node& lastNode = at(block->last());
+ return lastNode.op == Branch && lastNode.child1().index() == m_compileIndex ? block->size() - 1 : UINT_MAX;
}
void nonSpeculativeValueToNumber(Node&);
@@ -1124,7 +1126,7 @@ private:
}
JITCompiler::Call callOperation(J_DFGOperation_ESS operation, GPRReg result, int startConstant, int numConstants)
{
- m_jit.setupArgumentsWithExecState(Imm32(startConstant), Imm32(numConstants));
+ m_jit.setupArgumentsWithExecState(TrustedImm32(startConstant), TrustedImm32(numConstants));
return appendCallWithExceptionCheckSetResult(operation, result);
}
JITCompiler::Call callOperation(J_DFGOperation_EPP operation, GPRReg result, GPRReg arg1, void* pointer)
@@ -1162,6 +1164,11 @@ private:
m_jit.setupArgumentsWithExecState(arg1);
return appendCallWithExceptionCheckSetResult(operation, result);
}
+ JITCompiler::Call callOperation(C_DFGOperation_EC operation, GPRReg result, JSCell* cell)
+ {
+ m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell));
+ return appendCallWithExceptionCheckSetResult(operation, result);
+ }
JITCompiler::Call callOperation(C_DFGOperation_ECC operation, GPRReg result, GPRReg arg1, JSCell* cell)
{
m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell));
@@ -1182,14 +1189,14 @@ private:
m_jit.setupArgumentsWithExecState(arg1, arg2);
return appendCallWithExceptionCheckSetResult(operation, result);
}
- JITCompiler::Call callOperation(J_DFGOperation_EJJ operation, GPRReg result, GPRReg arg1, MacroAssembler::Imm32 imm)
+ JITCompiler::Call callOperation(J_DFGOperation_EJJ operation, GPRReg result, GPRReg arg1, MacroAssembler::TrustedImm32 imm)
{
- m_jit.setupArgumentsWithExecState(arg1, MacroAssembler::ImmPtr(static_cast<const void*>(JSValue::encode(jsNumber(imm.m_value)))));
+ m_jit.setupArgumentsWithExecState(arg1, MacroAssembler::TrustedImmPtr(static_cast<const void*>(JSValue::encode(jsNumber(imm.m_value)))));
return appendCallWithExceptionCheckSetResult(operation, result);
}
- JITCompiler::Call callOperation(J_DFGOperation_EJJ operation, GPRReg result, MacroAssembler::Imm32 imm, GPRReg arg2)
+ JITCompiler::Call callOperation(J_DFGOperation_EJJ operation, GPRReg result, MacroAssembler::TrustedImm32 imm, GPRReg arg2)
{
- m_jit.setupArgumentsWithExecState(MacroAssembler::ImmPtr(static_cast<const void*>(JSValue::encode(jsNumber(imm.m_value)))), arg2);
+ m_jit.setupArgumentsWithExecState(MacroAssembler::TrustedImmPtr(static_cast<const void*>(JSValue::encode(jsNumber(imm.m_value)))), arg2);
return appendCallWithExceptionCheckSetResult(operation, result);
}
JITCompiler::Call callOperation(J_DFGOperation_ECJ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
@@ -1197,6 +1204,11 @@ private:
m_jit.setupArgumentsWithExecState(arg1, arg2);
return appendCallWithExceptionCheckSetResult(operation, result);
}
+ JITCompiler::Call callOperation(V_DFGOperation_EC operation, GPRReg arg1)
+ {
+ m_jit.setupArgumentsWithExecState(arg1);
+ return appendCallWithExceptionCheck(operation);
+ }
JITCompiler::Call callOperation(V_DFGOperation_EJPP operation, GPRReg arg1, GPRReg arg2, void* pointer)
{
m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(pointer));
@@ -1287,7 +1299,7 @@ private:
}
JITCompiler::Call callOperation(J_DFGOperation_EJP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, void* pointer)
{
- m_jit.setupArgumentsWithExecState(arg1Payload, arg1Tag, ImmPtr(pointer));
+ m_jit.setupArgumentsWithExecState(arg1Payload, arg1Tag, TrustedImmPtr(pointer));
return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
}
JITCompiler::Call callOperation(J_DFGOperation_EJP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2)
@@ -1330,6 +1342,11 @@ private:
m_jit.setupArgumentsWithExecState(arg1);
return appendCallWithExceptionCheckSetResult(operation, result);
}
+ JITCompiler::Call callOperation(C_DFGOperation_EC operation, GPRReg result, JSCell* cell)
+ {
+ m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell));
+ return appendCallWithExceptionCheckSetResult(operation, result);
+ }
JITCompiler::Call callOperation(C_DFGOperation_ECC operation, GPRReg result, GPRReg arg1, JSCell* cell)
{
m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell));
@@ -1350,12 +1367,12 @@ private:
m_jit.setupArgumentsWithExecState(arg1Payload, arg1Tag, arg2Payload, arg2Tag);
return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
}
- JITCompiler::Call callOperation(J_DFGOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, MacroAssembler::Imm32 imm)
+ JITCompiler::Call callOperation(J_DFGOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, MacroAssembler::TrustedImm32 imm)
{
m_jit.setupArgumentsWithExecState(arg1Payload, arg1Tag, imm, TrustedImm32(JSValue::Int32Tag));
return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
}
- JITCompiler::Call callOperation(J_DFGOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, MacroAssembler::Imm32 imm, GPRReg arg2Tag, GPRReg arg2Payload)
+ JITCompiler::Call callOperation(J_DFGOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, MacroAssembler::TrustedImm32 imm, GPRReg arg2Tag, GPRReg arg2Payload)
{
m_jit.setupArgumentsWithExecState(imm, TrustedImm32(JSValue::Int32Tag), arg2Payload, arg2Tag);
return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
@@ -1365,6 +1382,11 @@ private:
m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag);
return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
}
+ JITCompiler::Call callOperation(V_DFGOperation_EC operation, GPRReg arg1)
+ {
+ m_jit.setupArgumentsWithExecState(arg1);
+ return appendCallWithExceptionCheck(operation);
+ }
JITCompiler::Call callOperation(V_DFGOperation_EJPP operation, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2, void* pointer)
{
m_jit.setupArgumentsWithExecState(arg1Payload, arg1Tag, arg2, TrustedImmPtr(pointer));
@@ -1620,7 +1642,7 @@ private:
{
if (!DFG_ENABLE_EDGE_CODE_VERIFICATION)
return;
- m_jit.move(Imm32(destination), GPRInfo::regT0);
+ m_jit.move(TrustedImm32(destination), GPRInfo::regT0);
}
void addBranch(const MacroAssembler::Jump& jump, BlockIndex destination)
@@ -1693,6 +1715,7 @@ private:
void compilePutByValForByteArray(GPRReg base, GPRReg property, Node&);
void compileAdd(Node&);
void compileArithSub(Node&);
+ void compileArithNegate(Node&);
void compileArithMul(Node&);
void compileArithMod(Node&);
void compileSoftModulo(Node&);
@@ -1715,14 +1738,18 @@ private:
void compilePutByValForIntTypedArray(const TypedArrayDescriptor&, GPRReg base, GPRReg property, Node&, size_t elementSize, TypedArraySpeculationRequirements, TypedArraySignedness, TypedArrayRounding = TruncateRounding);
void compileGetByValOnFloatTypedArray(const TypedArrayDescriptor&, Node&, size_t elementSize, TypedArraySpeculationRequirements);
void compilePutByValForFloatTypedArray(const TypedArrayDescriptor&, GPRReg base, GPRReg property, Node&, size_t elementSize, TypedArraySpeculationRequirements);
+ void compileNewFunctionNoCheck(Node& node);
+ void compileNewFunctionExpression(Node& node);
- // It is acceptable to have structure be equal to scratch, so long as you're fine
- // with the structure GPR being clobbered.
- template<typename T>
- void emitAllocateJSFinalObject(T structure, GPRReg resultGPR, GPRReg scratchGPR, MacroAssembler::JumpList& slowPath)
+ template <typename ClassType, bool destructor, typename StructureType>
+ void emitAllocateBasicJSObject(StructureType structure, GPRReg resultGPR, GPRReg scratchGPR, MacroAssembler::JumpList& slowPath)
{
- MarkedAllocator* allocator = &m_jit.globalData()->heap.allocatorForObjectWithoutDestructor(sizeof(JSFinalObject));
-
+ MarkedAllocator* allocator = 0;
+ if (destructor)
+ allocator = &m_jit.globalData()->heap.allocatorForObjectWithDestructor(sizeof(ClassType));
+ else
+ allocator = &m_jit.globalData()->heap.allocatorForObjectWithoutDestructor(sizeof(ClassType));
+
m_jit.loadPtr(&allocator->m_firstFreeCell, resultGPR);
slowPath.append(m_jit.branchTestPtr(MacroAssembler::Zero, resultGPR));
@@ -1738,14 +1765,22 @@ private:
m_jit.storePtr(scratchGPR, &allocator->m_firstFreeCell);
// Initialize the object's classInfo pointer
- m_jit.storePtr(MacroAssembler::TrustedImmPtr(&JSFinalObject::s_info), MacroAssembler::Address(resultGPR, JSCell::classInfoOffset()));
+ m_jit.storePtr(MacroAssembler::TrustedImmPtr(&ClassType::s_info), MacroAssembler::Address(resultGPR, JSCell::classInfoOffset()));
// Initialize the object's inheritorID.
m_jit.storePtr(MacroAssembler::TrustedImmPtr(0), MacroAssembler::Address(resultGPR, JSObject::offsetOfInheritorID()));
// Initialize the object's property storage pointer.
m_jit.addPtr(MacroAssembler::TrustedImm32(sizeof(JSObject)), resultGPR, scratchGPR);
- m_jit.storePtr(scratchGPR, MacroAssembler::Address(resultGPR, JSFinalObject::offsetOfPropertyStorage()));
+ m_jit.storePtr(scratchGPR, MacroAssembler::Address(resultGPR, ClassType::offsetOfPropertyStorage()));
+ }
+
+ // It is acceptable to have structure be equal to scratch, so long as you're fine
+ // with the structure GPR being clobbered.
+ template<typename T>
+ void emitAllocateJSFinalObject(T structure, GPRReg resultGPR, GPRReg scratchGPR, MacroAssembler::JumpList& slowPath)
+ {
+ return emitAllocateBasicJSObject<JSFinalObject, false>(structure, resultGPR, scratchGPR, slowPath);
}
#if USE(JSVALUE64)
@@ -1849,6 +1884,7 @@ private:
// The current node being generated.
BlockIndex m_block;
NodeIndex m_compileIndex;
+ unsigned m_indexInBlock;
// Virtual and physical register maps.
Vector<GenerationInfo, 32> m_generationInfo;
RegisterBank<GPRInfo> m_gprs;
@@ -2482,6 +2518,7 @@ inline SpeculativeJIT::SpeculativeJIT(JITCompiler& jit)
: m_compileOkay(true)
, m_jit(jit)
, m_compileIndex(0)
+ , m_indexInBlock(0)
, m_generationInfo(m_jit.codeBlock()->m_numCalleeRegisters)
, m_blockHeads(jit.graph().m_blocks.size())
, m_arguments(jit.codeBlock()->numParameters())
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
index 8c4d8c030..b6814229c 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
@@ -652,14 +652,17 @@ void SpeculativeJIT::nonSpeculativePeepholeBranchNull(NodeUse operand, NodeIndex
bool SpeculativeJIT::nonSpeculativeCompareNull(Node& node, NodeUse operand, bool invert)
{
- NodeIndex branchNodeIndex = detectPeepHoleBranch();
- if (branchNodeIndex != NoNode) {
+ unsigned branchIndexInBlock = detectPeepHoleBranch();
+ if (branchIndexInBlock != UINT_MAX) {
+ NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
+
ASSERT(node.adjustedRefCount() == 1);
nonSpeculativePeepholeBranchNull(operand, branchNodeIndex, invert);
use(node.child1());
use(node.child2());
+ m_indexInBlock = branchIndexInBlock;
m_compileIndex = branchNodeIndex;
return true;
@@ -947,7 +950,7 @@ void SpeculativeJIT::emitCall(Node& node)
m_jit.storePtr(resultPayloadGPR, callFramePayloadSlot(RegisterFile::ScopeChain));
m_jit.store32(MacroAssembler::TrustedImm32(JSValue::CellTag), callFrameTagSlot(RegisterFile::ScopeChain));
- m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister);
+ m_jit.addPtr(TrustedImm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister);
CodeOrigin codeOrigin = at(m_compileIndex).codeOrigin;
CallBeginToken token = m_jit.beginJSCall();
@@ -958,12 +961,12 @@ void SpeculativeJIT::emitCall(Node& node)
slowPath.link(&m_jit);
- m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+ m_jit.addPtr(TrustedImm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
m_jit.poke(GPRInfo::argumentGPR0);
token = m_jit.beginCall();
JITCompiler::Call slowCall = m_jit.appendCall(slowCallFunction);
m_jit.addFastExceptionCheck(slowCall, codeOrigin, token);
- m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister);
+ m_jit.addPtr(TrustedImm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister);
token = m_jit.beginJSCall();
JITCompiler::Call theCall = m_jit.call(GPRInfo::returnValueGPR);
m_jit.notifyCall(theCall, codeOrigin, token);
@@ -1387,10 +1390,10 @@ void SpeculativeJIT::compileObjectEquality(Node& node, const ClassInfo* classInf
GPRReg resultPayloadGPR = resultPayload.gpr();
MacroAssembler::Jump falseCase = m_jit.branchPtr(MacroAssembler::NotEqual, op1GPR, op2GPR);
- m_jit.move(Imm32(1), resultPayloadGPR);
+ m_jit.move(TrustedImm32(1), resultPayloadGPR);
MacroAssembler::Jump done = m_jit.jump();
falseCase.link(&m_jit);
- m_jit.move(Imm32(0), resultPayloadGPR);
+ m_jit.move(TrustedImm32(0), resultPayloadGPR);
done.link(&m_jit);
booleanResult(resultPayloadGPR, m_compileIndex);
@@ -1414,9 +1417,9 @@ void SpeculativeJIT::compileDoubleCompare(Node& node, MacroAssembler::DoubleCond
SpeculateDoubleOperand op2(this, node.child2());
GPRTemporary resultPayload(this);
- m_jit.move(Imm32(1), resultPayload.gpr());
+ m_jit.move(TrustedImm32(1), resultPayload.gpr());
MacroAssembler::Jump trueCase = m_jit.branchDouble(condition, op1.fpr(), op2.fpr());
- m_jit.move(Imm32(0), resultPayload.gpr());
+ m_jit.move(TrustedImm32(0), resultPayload.gpr());
trueCase.link(&m_jit);
booleanResult(resultPayload.gpr(), m_compileIndex);
@@ -1637,7 +1640,7 @@ void SpeculativeJIT::emitBranch(Node& node)
void SpeculativeJIT::compile(Node& node)
{
- NodeType op = node.op;
+ NodeType op = static_cast<NodeType>(node.op);
switch (op) {
case JSConstant:
@@ -1654,54 +1657,59 @@ void SpeculativeJIT::compile(Node& node)
AbstractValue& value = block()->valuesAtHead.operand(node.local());
// If we have no prediction for this local, then don't attempt to compile.
- if (prediction == PredictNone) {
+ if (prediction == PredictNone || value.isClear()) {
terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
break;
}
- if (node.variableAccessData()->shouldUseDoubleFormat()) {
- FPRTemporary result(this);
- m_jit.loadDouble(JITCompiler::addressFor(node.local()), result.fpr());
- VirtualRegister virtualRegister = node.virtualRegister();
- m_fprs.retain(result.fpr(), virtualRegister, SpillOrderDouble);
- m_generationInfo[virtualRegister].initDouble(m_compileIndex, node.refCount(), result.fpr());
- break;
- }
+ if (!m_jit.graph().isCaptured(node.local())) {
+ if (node.variableAccessData()->shouldUseDoubleFormat()) {
+ FPRTemporary result(this);
+ m_jit.loadDouble(JITCompiler::addressFor(node.local()), result.fpr());
+ VirtualRegister virtualRegister = node.virtualRegister();
+ m_fprs.retain(result.fpr(), virtualRegister, SpillOrderDouble);
+ m_generationInfo[virtualRegister].initDouble(m_compileIndex, node.refCount(), result.fpr());
+ break;
+ }
- GPRTemporary result(this);
- if (isInt32Prediction(prediction)) {
- m_jit.load32(JITCompiler::payloadFor(node.local()), result.gpr());
-
- // Like integerResult, but don't useChildren - our children are phi nodes,
- // and don't represent values within this dataflow with virtual registers.
- VirtualRegister virtualRegister = node.virtualRegister();
- m_gprs.retain(result.gpr(), virtualRegister, SpillOrderInteger);
- m_generationInfo[virtualRegister].initInteger(m_compileIndex, node.refCount(), result.gpr());
- break;
- }
+ if (isInt32Prediction(prediction)) {
+ GPRTemporary result(this);
+ m_jit.load32(JITCompiler::payloadFor(node.local()), result.gpr());
- if (isArrayPrediction(prediction) || isByteArrayPrediction(prediction)) {
- m_jit.load32(JITCompiler::payloadFor(node.local()), result.gpr());
+ // Like integerResult, but don't useChildren - our children are phi nodes,
+ // and don't represent values within this dataflow with virtual registers.
+ VirtualRegister virtualRegister = node.virtualRegister();
+ m_gprs.retain(result.gpr(), virtualRegister, SpillOrderInteger);
+ m_generationInfo[virtualRegister].initInteger(m_compileIndex, node.refCount(), result.gpr());
+ break;
+ }
- // Like cellResult, but don't useChildren - our children are phi nodes,
- // and don't represent values within this dataflow with virtual registers.
- VirtualRegister virtualRegister = node.virtualRegister();
- m_gprs.retain(result.gpr(), virtualRegister, SpillOrderCell);
- m_generationInfo[virtualRegister].initCell(m_compileIndex, node.refCount(), result.gpr());
- break;
- }
+ if (isArrayPrediction(prediction) || isByteArrayPrediction(prediction)) {
+ GPRTemporary result(this);
+ m_jit.load32(JITCompiler::payloadFor(node.local()), result.gpr());
+
+ // Like cellResult, but don't useChildren - our children are phi nodes,
+ // and don't represent values within this dataflow with virtual registers.
+ VirtualRegister virtualRegister = node.virtualRegister();
+ m_gprs.retain(result.gpr(), virtualRegister, SpillOrderCell);
+ m_generationInfo[virtualRegister].initCell(m_compileIndex, node.refCount(), result.gpr());
+ break;
+ }
- if (isBooleanPrediction(prediction)) {
- m_jit.load32(JITCompiler::payloadFor(node.local()), result.gpr());
+ if (isBooleanPrediction(prediction)) {
+ GPRTemporary result(this);
+ m_jit.load32(JITCompiler::payloadFor(node.local()), result.gpr());
- // Like booleanResult, but don't useChildren - our children are phi nodes,
- // and don't represent values within this dataflow with virtual registers.
- VirtualRegister virtualRegister = node.virtualRegister();
- m_gprs.retain(result.gpr(), virtualRegister, SpillOrderBoolean);
- m_generationInfo[virtualRegister].initBoolean(m_compileIndex, node.refCount(), result.gpr());
- break;
+ // Like booleanResult, but don't useChildren - our children are phi nodes,
+ // and don't represent values within this dataflow with virtual registers.
+ VirtualRegister virtualRegister = node.virtualRegister();
+ m_gprs.retain(result.gpr(), virtualRegister, SpillOrderBoolean);
+ m_generationInfo[virtualRegister].initBoolean(m_compileIndex, node.refCount(), result.gpr());
+ break;
+ }
}
+ GPRTemporary result(this);
GPRTemporary tag(this);
m_jit.load32(JITCompiler::payloadFor(node.local()), result.gpr());
m_jit.load32(JITCompiler::tagFor(node.local()), tag.gpr());
@@ -1712,7 +1720,12 @@ void SpeculativeJIT::compile(Node& node)
m_gprs.retain(result.gpr(), virtualRegister, SpillOrderJS);
m_gprs.retain(tag.gpr(), virtualRegister, SpillOrderJS);
- DataFormat format = isCellPrediction(value.m_type) ? DataFormatJSCell : DataFormatJS;
+ DataFormat format;
+ if (isCellPrediction(value.m_type)
+ && !m_jit.graph().isCaptured(node.local()))
+ format = DataFormatJSCell;
+ else
+ format = DataFormatJS;
m_generationInfo[virtualRegister].initJSValue(m_compileIndex, node.refCount(), tag.gpr(), result.gpr(), format);
break;
}
@@ -1733,53 +1746,65 @@ void SpeculativeJIT::compile(Node& node)
m_codeOriginForOSR = nextNode.codeOrigin;
- if (node.variableAccessData()->shouldUseDoubleFormat()) {
- SpeculateDoubleOperand value(this, node.child1());
- m_jit.storeDouble(value.fpr(), JITCompiler::addressFor(node.local()));
- noResult(m_compileIndex);
- // Indicate that it's no longer necessary to retrieve the value of
- // this bytecode variable from registers or other locations in the register file,
- // but that it is stored as a double.
- valueSourceReferenceForOperand(node.local()) = ValueSource(DoubleInRegisterFile);
- } else {
+ if (!m_jit.graph().isCaptured(node.local())) {
+ if (node.variableAccessData()->shouldUseDoubleFormat()) {
+ SpeculateDoubleOperand value(this, node.child1());
+ m_jit.storeDouble(value.fpr(), JITCompiler::addressFor(node.local()));
+ noResult(m_compileIndex);
+ // Indicate that it's no longer necessary to retrieve the value of
+ // this bytecode variable from registers or other locations in the register file,
+ // but that it is stored as a double.
+ valueSourceReferenceForOperand(node.local()) = ValueSource(DoubleInRegisterFile);
+ break;
+ }
PredictedType predictedType = node.variableAccessData()->prediction();
if (m_generationInfo[at(node.child1()).virtualRegister()].registerFormat() == DataFormatDouble) {
DoubleOperand value(this, node.child1());
m_jit.storeDouble(value.fpr(), JITCompiler::addressFor(node.local()));
noResult(m_compileIndex);
- } else if (isInt32Prediction(predictedType)) {
+ valueSourceReferenceForOperand(node.local()) = ValueSource(DoubleInRegisterFile);
+ break;
+ }
+ if (isInt32Prediction(predictedType)) {
SpeculateIntegerOperand value(this, node.child1());
m_jit.store32(value.gpr(), JITCompiler::payloadFor(node.local()));
noResult(m_compileIndex);
- } else if (isArrayPrediction(predictedType)) {
+ valueSourceReferenceForOperand(node.local()) = ValueSource(Int32InRegisterFile);
+ break;
+ }
+ if (isArrayPrediction(predictedType)) {
SpeculateCellOperand cell(this, node.child1());
GPRReg cellGPR = cell.gpr();
if (!isArrayPrediction(m_state.forNode(node.child1()).m_type))
speculationCheck(BadType, JSValueSource::unboxedCell(cellGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(cellGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info)));
m_jit.storePtr(cellGPR, JITCompiler::payloadFor(node.local()));
noResult(m_compileIndex);
- } else if (isByteArrayPrediction(predictedType)) {
+ valueSourceReferenceForOperand(node.local()) = ValueSource(CellInRegisterFile);
+ break;
+ }
+ if (isByteArrayPrediction(predictedType)) {
SpeculateCellOperand cell(this, node.child1());
GPRReg cellGPR = cell.gpr();
if (!isByteArrayPrediction(m_state.forNode(node.child1()).m_type))
speculationCheck(BadType, JSValueSource::unboxedCell(cellGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(cellGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSByteArray::s_info)));
m_jit.storePtr(cellGPR, JITCompiler::payloadFor(node.local()));
noResult(m_compileIndex);
- } else if (isBooleanPrediction(predictedType)) {
+ valueSourceReferenceForOperand(node.local()) = ValueSource(CellInRegisterFile);
+ break;
+ }
+ if (isBooleanPrediction(predictedType)) {
SpeculateBooleanOperand value(this, node.child1());
m_jit.store32(value.gpr(), JITCompiler::payloadFor(node.local()));
noResult(m_compileIndex);
- } else {
- JSValueOperand value(this, node.child1());
- m_jit.store32(value.payloadGPR(), JITCompiler::payloadFor(node.local()));
- m_jit.store32(value.tagGPR(), JITCompiler::tagFor(node.local()));
- noResult(m_compileIndex);
+ valueSourceReferenceForOperand(node.local()) = ValueSource(BooleanInRegisterFile);
+ break;
}
-
- // Indicate that it's no longer necessary to retrieve the value of
- // this bytecode variable from registers or other locations in the register file.
- valueSourceReferenceForOperand(node.local()) = ValueSource::forPrediction(predictedType);
}
+ JSValueOperand value(this, node.child1());
+ m_jit.store32(value.payloadGPR(), JITCompiler::payloadFor(node.local()));
+ m_jit.store32(value.tagGPR(), JITCompiler::tagFor(node.local()));
+ noResult(m_compileIndex);
+ valueSourceReferenceForOperand(node.local()) = ValueSource(ValueInRegisterFile);
break;
}
@@ -1863,6 +1888,10 @@ void SpeculativeJIT::compile(Node& node)
compileArithSub(node);
break;
+ case ArithNegate:
+ compileArithNegate(node);
+ break;
+
case ArithMul:
compileArithMul(node);
break;
@@ -1951,7 +1980,7 @@ void SpeculativeJIT::compile(Node& node)
case ArithAbs: {
if (at(node.child1()).shouldSpeculateInteger() && node.canSpeculateInteger()) {
SpeculateIntegerOperand op1(this, node.child1());
- GPRTemporary result(this);
+ GPRTemporary result(this, op1);
GPRTemporary scratch(this);
m_jit.zeroExtend32ToPtr(op1.gpr(), result.gpr());
@@ -2350,7 +2379,7 @@ void SpeculativeJIT::compile(Node& node)
// Code to handle put beyond array bounds.
silentSpillAllRegisters(scratchReg);
- callOperation(operationPutByValBeyondArrayBounds, baseReg, propertyReg, valueTagReg, valuePayloadReg);
+ callOperation(m_jit.codeBlock()->isStrictMode() ? operationPutByValBeyondArrayBoundsStrict : operationPutByValBeyondArrayBoundsNonStrict, baseReg, propertyReg, valueTagReg, valuePayloadReg);
silentFillAllRegisters(scratchReg);
JITCompiler::Jump wasBeyondArrayBounds = m_jit.jump();
@@ -2514,10 +2543,10 @@ void SpeculativeJIT::compile(Node& node)
m_jit.store32(valueTagGPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
m_jit.store32(valuePayloadGPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
- m_jit.add32(Imm32(1), storageLengthGPR);
+ m_jit.add32(TrustedImm32(1), storageLengthGPR);
m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_length)));
- m_jit.add32(Imm32(1), MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
- m_jit.move(Imm32(JSValue::Int32Tag), storageGPR);
+ m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
+ m_jit.move(TrustedImm32(JSValue::Int32Tag), storageGPR);
MacroAssembler::Jump done = m_jit.jump();
@@ -2554,7 +2583,7 @@ void SpeculativeJIT::compile(Node& node)
MacroAssembler::Jump emptyArrayCase = m_jit.branchTest32(MacroAssembler::Zero, storageLengthGPR);
- m_jit.sub32(Imm32(1), storageLengthGPR);
+ m_jit.sub32(TrustedImm32(1), storageLengthGPR);
MacroAssembler::Jump slowCase = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(baseGPR, JSArray::vectorLengthOffset()));
@@ -2563,11 +2592,11 @@ void SpeculativeJIT::compile(Node& node)
m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_length)));
- MacroAssembler::Jump holeCase = m_jit.branch32(MacroAssembler::Equal, Imm32(JSValue::EmptyValueTag), valueTagGPR);
+ MacroAssembler::Jump holeCase = m_jit.branch32(MacroAssembler::Equal, TrustedImm32(JSValue::EmptyValueTag), valueTagGPR);
m_jit.store32(TrustedImm32(JSValue::EmptyValueTag), MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
- m_jit.sub32(MacroAssembler::Imm32(1), MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
+ m_jit.sub32(TrustedImm32(1), MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
MacroAssembler::JumpList done;
@@ -2575,8 +2604,8 @@ void SpeculativeJIT::compile(Node& node)
holeCase.link(&m_jit);
emptyArrayCase.link(&m_jit);
- m_jit.move(MacroAssembler::Imm32(jsUndefined().tag()), valueTagGPR);
- m_jit.move(MacroAssembler::Imm32(jsUndefined().payload()), valuePayloadGPR);
+ m_jit.move(MacroAssembler::TrustedImm32(jsUndefined().tag()), valueTagGPR);
+ m_jit.move(MacroAssembler::TrustedImm32(jsUndefined().payload()), valuePayloadGPR);
done.append(m_jit.jump());
slowCase.link(&m_jit);
@@ -3384,7 +3413,7 @@ void SpeculativeJIT::compile(Node& node)
case Phi:
case Flush:
- ASSERT_NOT_REACHED();
+ break;
case Breakpoint:
#if ENABLE(DEBUG_WITH_BREAKPOINT)
@@ -3466,6 +3495,77 @@ void SpeculativeJIT::compile(Node& node)
break;
}
+ case CreateActivation: {
+ JSValueOperand value(this, node.child1());
+ GPRTemporary result(this, value, false);
+
+ GPRReg valueTagGPR = value.tagGPR();
+ GPRReg valuePayloadGPR = value.payloadGPR();
+ GPRReg resultGPR = result.gpr();
+
+ m_jit.move(valuePayloadGPR, resultGPR);
+
+ JITCompiler::Jump alreadyCreated = m_jit.branch32(JITCompiler::NotEqual, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
+
+ silentSpillAllRegisters(resultGPR);
+ callOperation(operationCreateActivation, resultGPR);
+ silentFillAllRegisters(resultGPR);
+
+ alreadyCreated.link(&m_jit);
+
+ cellResult(resultGPR, m_compileIndex);
+ break;
+ }
+
+ case TearOffActivation: {
+ JSValueOperand value(this, node.child1());
+
+ GPRReg valueTagGPR = value.tagGPR();
+ GPRReg valuePayloadGPR = value.payloadGPR();
+
+ JITCompiler::Jump notCreated = m_jit.branch32(JITCompiler::Equal, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
+
+ silentSpillAllRegisters(InvalidGPRReg);
+ callOperation(operationTearOffActivation, valuePayloadGPR);
+ silentFillAllRegisters(InvalidGPRReg);
+
+ notCreated.link(&m_jit);
+
+ noResult(m_compileIndex);
+ break;
+ }
+
+ case NewFunctionNoCheck:
+ compileNewFunctionNoCheck(node);
+ break;
+
+ case NewFunction: {
+ JSValueOperand value(this, node.child1());
+ GPRTemporary result(this, value, false);
+
+ GPRReg valueTagGPR = value.tagGPR();
+ GPRReg valuePayloadGPR = value.payloadGPR();
+ GPRReg resultGPR = result.gpr();
+
+ m_jit.move(valuePayloadGPR, resultGPR);
+
+ JITCompiler::Jump alreadyCreated = m_jit.branch32(JITCompiler::NotEqual, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
+
+ silentSpillAllRegisters(resultGPR);
+ callOperation(
+ operationNewFunction, resultGPR, m_jit.codeBlock()->functionDecl(node.functionDeclIndex()));
+ silentFillAllRegisters(resultGPR);
+
+ alreadyCreated.link(&m_jit);
+
+ cellResult(resultGPR, m_compileIndex);
+ break;
+ }
+
+ case NewFunctionExpression:
+ compileNewFunctionExpression(node);
+ break;
+
case ForceOSRExit: {
terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
break;
@@ -3478,10 +3578,11 @@ void SpeculativeJIT::compile(Node& node)
case InlineStart:
case Nop:
+ case LastNodeType:
ASSERT_NOT_REACHED();
break;
}
-
+
if (!m_compileOkay)
return;
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
index 6d375f81f..1597b1674 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
@@ -57,7 +57,7 @@ GPRReg SpeculativeJIT::fillInteger(NodeIndex nodeIndex, DataFormat& returnFormat
} else {
ASSERT(isJSConstant(nodeIndex));
JSValue jsValue = valueOfJSConstant(nodeIndex);
- m_jit.move(MacroAssembler::ImmPtr(JSValue::encode(jsValue)), gpr);
+ m_jit.move(MacroAssembler::TrustedImmPtr(JSValue::encode(jsValue)), gpr);
}
} else if (info.spillFormat() == DataFormatInteger) {
m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
@@ -141,7 +141,7 @@ FPRReg SpeculativeJIT::fillDouble(NodeIndex nodeIndex)
// FIXME: should not be reachable?
ASSERT(isJSConstant(nodeIndex));
JSValue jsValue = valueOfJSConstant(nodeIndex);
- m_jit.move(MacroAssembler::ImmPtr(JSValue::encode(jsValue)), gpr);
+ m_jit.move(MacroAssembler::TrustedImmPtr(JSValue::encode(jsValue)), gpr);
m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
info.fillJSValue(gpr, DataFormatJS);
unlock(gpr);
@@ -283,7 +283,7 @@ GPRReg SpeculativeJIT::fillJSValue(NodeIndex nodeIndex)
} else {
ASSERT(isJSConstant(nodeIndex));
JSValue jsValue = valueOfJSConstant(nodeIndex);
- m_jit.move(MacroAssembler::ImmPtr(JSValue::encode(jsValue)), gpr);
+ m_jit.move(MacroAssembler::TrustedImmPtr(JSValue::encode(jsValue)), gpr);
info.fillJSValue(gpr, DataFormatJS);
}
@@ -628,14 +628,17 @@ void SpeculativeJIT::nonSpeculativePeepholeBranchNull(NodeUse operand, NodeIndex
bool SpeculativeJIT::nonSpeculativeCompareNull(Node& node, NodeUse operand, bool invert)
{
- NodeIndex branchNodeIndex = detectPeepHoleBranch();
- if (branchNodeIndex != NoNode) {
+ unsigned branchIndexInBlock = detectPeepHoleBranch();
+ if (branchIndexInBlock != UINT_MAX) {
+ NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
+
ASSERT(node.adjustedRefCount() == 1);
nonSpeculativePeepholeBranchNull(operand, branchNodeIndex, invert);
use(node.child1());
use(node.child2());
+ m_indexInBlock = branchIndexInBlock;
m_compileIndex = branchNodeIndex;
return true;
@@ -808,15 +811,21 @@ void SpeculativeJIT::nonSpeculativePeepholeStrictEq(Node& node, NodeIndex branch
JITCompiler::Jump twoCellsCase = m_jit.branchTestPtr(JITCompiler::Zero, resultGPR, GPRInfo::tagMaskRegister);
- JITCompiler::Jump numberCase = m_jit.branchTestPtr(JITCompiler::NonZero, resultGPR, GPRInfo::tagTypeNumberRegister);
+ JITCompiler::Jump leftOK = m_jit.branchPtr(JITCompiler::AboveOrEqual, arg1GPR, GPRInfo::tagTypeNumberRegister);
+ JITCompiler::Jump leftDouble = m_jit.branchTestPtr(JITCompiler::NonZero, arg1GPR, GPRInfo::tagTypeNumberRegister);
+ leftOK.link(&m_jit);
+ JITCompiler::Jump rightOK = m_jit.branchPtr(JITCompiler::AboveOrEqual, arg2GPR, GPRInfo::tagTypeNumberRegister);
+ JITCompiler::Jump rightDouble = m_jit.branchTestPtr(JITCompiler::NonZero, arg2GPR, GPRInfo::tagTypeNumberRegister);
+ rightOK.link(&m_jit);
- branch32(invert ? JITCompiler::NotEqual : JITCompiler::Equal, arg1GPR, arg2GPR, taken);
+ branchPtr(invert ? JITCompiler::NotEqual : JITCompiler::Equal, arg1GPR, arg2GPR, taken);
jump(notTaken, ForceJump);
twoCellsCase.link(&m_jit);
branchPtr(JITCompiler::Equal, arg1GPR, arg2GPR, invert ? notTaken : taken);
- numberCase.link(&m_jit);
+ leftDouble.link(&m_jit);
+ rightDouble.link(&m_jit);
silentSpillAllRegisters(resultGPR);
callOperation(operationCompareStrictEq, resultGPR, arg1GPR, arg2GPR);
@@ -865,9 +874,14 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeStrictEq(Node& node, bool invert)
JITCompiler::Jump twoCellsCase = m_jit.branchTestPtr(JITCompiler::Zero, resultGPR, GPRInfo::tagMaskRegister);
- JITCompiler::Jump numberCase = m_jit.branchTestPtr(JITCompiler::NonZero, resultGPR, GPRInfo::tagTypeNumberRegister);
+ JITCompiler::Jump leftOK = m_jit.branchPtr(JITCompiler::AboveOrEqual, arg1GPR, GPRInfo::tagTypeNumberRegister);
+ JITCompiler::Jump leftDouble = m_jit.branchTestPtr(JITCompiler::NonZero, arg1GPR, GPRInfo::tagTypeNumberRegister);
+ leftOK.link(&m_jit);
+ JITCompiler::Jump rightOK = m_jit.branchPtr(JITCompiler::AboveOrEqual, arg2GPR, GPRInfo::tagTypeNumberRegister);
+ JITCompiler::Jump rightDouble = m_jit.branchTestPtr(JITCompiler::NonZero, arg2GPR, GPRInfo::tagTypeNumberRegister);
+ rightOK.link(&m_jit);
- m_jit.compare32(invert ? JITCompiler::NotEqual : JITCompiler::Equal, arg1GPR, arg2GPR, resultGPR);
+ m_jit.comparePtr(invert ? JITCompiler::NotEqual : JITCompiler::Equal, arg1GPR, arg2GPR, resultGPR);
JITCompiler::Jump done1 = m_jit.jump();
@@ -878,7 +892,8 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeStrictEq(Node& node, bool invert)
JITCompiler::Jump done2 = m_jit.jump();
- numberCase.link(&m_jit);
+ leftDouble.link(&m_jit);
+ rightDouble.link(&m_jit);
notEqualCase.link(&m_jit);
silentSpillAllRegisters(resultGPR);
@@ -948,7 +963,7 @@ void SpeculativeJIT::emitCall(Node& node)
m_jit.loadPtr(MacroAssembler::Address(calleeGPR, OBJECT_OFFSETOF(JSFunction, m_scopeChain)), resultGPR);
m_jit.storePtr(resultGPR, callFrameSlot(RegisterFile::ScopeChain));
- m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister);
+ m_jit.addPtr(TrustedImm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister);
CodeOrigin codeOrigin = at(m_compileIndex).codeOrigin;
CallBeginToken token = m_jit.beginJSCall();
@@ -959,11 +974,11 @@ void SpeculativeJIT::emitCall(Node& node)
slowPath.link(&m_jit);
- m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+ m_jit.addPtr(TrustedImm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
token = m_jit.beginCall();
JITCompiler::Call slowCall = m_jit.appendCall(slowCallFunction);
m_jit.addFastExceptionCheck(slowCall, codeOrigin, token);
- m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister);
+ m_jit.addPtr(TrustedImm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister);
token = m_jit.beginJSCall();
JITCompiler::Call theCall = m_jit.call(GPRInfo::returnValueGPR);
m_jit.notifyCall(theCall, codeOrigin, token);
@@ -1461,10 +1476,10 @@ void SpeculativeJIT::compileObjectEquality(Node& node, const ClassInfo* classInf
speculationCheck(BadType, JSValueRegs(op2GPR), node.child2().index(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op2GPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(classInfo)));
MacroAssembler::Jump falseCase = m_jit.branchPtr(MacroAssembler::NotEqual, op1GPR, op2GPR);
- m_jit.move(Imm32(ValueTrue), resultGPR);
+ m_jit.move(TrustedImm32(ValueTrue), resultGPR);
MacroAssembler::Jump done = m_jit.jump();
falseCase.link(&m_jit);
- m_jit.move(Imm32(ValueFalse), resultGPR);
+ m_jit.move(TrustedImm32(ValueFalse), resultGPR);
done.link(&m_jit);
jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean);
@@ -1491,7 +1506,7 @@ void SpeculativeJIT::compileDoubleCompare(Node& node, MacroAssembler::DoubleCond
m_jit.move(TrustedImm32(ValueTrue), result.gpr());
MacroAssembler::Jump trueCase = m_jit.branchDouble(condition, op1.fpr(), op2.fpr());
- m_jit.xorPtr(Imm32(true), result.gpr());
+ m_jit.xorPtr(TrustedImm32(true), result.gpr());
trueCase.link(&m_jit);
jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
@@ -1577,7 +1592,7 @@ void SpeculativeJIT::compileLogicalNot(Node& node)
GPRTemporary result(this);
m_jit.move(TrustedImm32(ValueFalse), result.gpr());
MacroAssembler::Jump nonZero = m_jit.branchDoubleNonZero(value.fpr(), scratch.fpr());
- m_jit.xor32(Imm32(true), result.gpr());
+ m_jit.xor32(TrustedImm32(true), result.gpr());
nonZero.link(&m_jit);
jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
return;
@@ -1699,18 +1714,18 @@ void SpeculativeJIT::emitBranch(Node& node)
bool predictBoolean = isBooleanPrediction(m_jit.getPrediction(node.child1()));
if (predictBoolean) {
- branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsBoolean(false))), notTaken);
- branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsBoolean(true))), taken);
+ branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::TrustedImmPtr(JSValue::encode(jsBoolean(false))), notTaken);
+ branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::TrustedImmPtr(JSValue::encode(jsBoolean(true))), taken);
speculationCheck(BadType, JSValueRegs(valueGPR), node.child1(), m_jit.jump());
value.use();
} else {
- branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsNumber(0))), notTaken);
+ branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::TrustedImmPtr(JSValue::encode(jsNumber(0))), notTaken);
branchPtr(MacroAssembler::AboveOrEqual, valueGPR, GPRInfo::tagTypeNumberRegister, taken);
if (!predictBoolean) {
- branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsBoolean(false))), notTaken);
- branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsBoolean(true))), taken);
+ branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::TrustedImmPtr(JSValue::encode(jsBoolean(false))), notTaken);
+ branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::TrustedImmPtr(JSValue::encode(jsBoolean(true))), taken);
}
value.use();
@@ -1729,7 +1744,7 @@ void SpeculativeJIT::emitBranch(Node& node)
void SpeculativeJIT::compile(Node& node)
{
- NodeType op = node.op;
+ NodeType op = static_cast<NodeType>(node.op);
switch (op) {
case JSConstant:
@@ -1751,27 +1766,30 @@ void SpeculativeJIT::compile(Node& node)
break;
}
- if (node.variableAccessData()->shouldUseDoubleFormat()) {
- FPRTemporary result(this);
- m_jit.loadDouble(JITCompiler::addressFor(node.local()), result.fpr());
- VirtualRegister virtualRegister = node.virtualRegister();
- m_fprs.retain(result.fpr(), virtualRegister, SpillOrderDouble);
- m_generationInfo[virtualRegister].initDouble(m_compileIndex, node.refCount(), result.fpr());
- break;
- }
-
- GPRTemporary result(this);
- if (isInt32Prediction(value.m_type)) {
- m_jit.load32(JITCompiler::payloadFor(node.local()), result.gpr());
-
- // Like integerResult, but don't useChildren - our children are phi nodes,
- // and don't represent values within this dataflow with virtual registers.
- VirtualRegister virtualRegister = node.virtualRegister();
- m_gprs.retain(result.gpr(), virtualRegister, SpillOrderInteger);
- m_generationInfo[virtualRegister].initInteger(m_compileIndex, node.refCount(), result.gpr());
- break;
+ if (!m_jit.graph().isCaptured(node.local())) {
+ if (node.variableAccessData()->shouldUseDoubleFormat()) {
+ FPRTemporary result(this);
+ m_jit.loadDouble(JITCompiler::addressFor(node.local()), result.fpr());
+ VirtualRegister virtualRegister = node.virtualRegister();
+ m_fprs.retain(result.fpr(), virtualRegister, SpillOrderDouble);
+ m_generationInfo[virtualRegister].initDouble(m_compileIndex, node.refCount(), result.fpr());
+ break;
+ }
+
+ if (isInt32Prediction(value.m_type)) {
+ GPRTemporary result(this);
+ m_jit.load32(JITCompiler::payloadFor(node.local()), result.gpr());
+
+ // Like integerResult, but don't useChildren - our children are phi nodes,
+ // and don't represent values within this dataflow with virtual registers.
+ VirtualRegister virtualRegister = node.virtualRegister();
+ m_gprs.retain(result.gpr(), virtualRegister, SpillOrderInteger);
+ m_generationInfo[virtualRegister].initInteger(m_compileIndex, node.refCount(), result.gpr());
+ break;
+ }
}
+ GPRTemporary result(this);
m_jit.loadPtr(JITCompiler::addressFor(node.local()), result.gpr());
// Like jsValueResult, but don't useChildren - our children are phi nodes,
@@ -1780,7 +1798,9 @@ void SpeculativeJIT::compile(Node& node)
m_gprs.retain(result.gpr(), virtualRegister, SpillOrderJS);
DataFormat format;
- if (isCellPrediction(value.m_type))
+ if (m_jit.graph().isCaptured(node.local()))
+ format = DataFormatJS;
+ else if (isCellPrediction(value.m_type))
format = DataFormatJSCell;
else if (isBooleanPrediction(value.m_type))
format = DataFormatJSBoolean;
@@ -1817,48 +1837,60 @@ void SpeculativeJIT::compile(Node& node)
// OSR exit, would not be visible to the old JIT in any way.
m_codeOriginForOSR = nextNode.codeOrigin;
- if (node.variableAccessData()->shouldUseDoubleFormat()) {
- SpeculateDoubleOperand value(this, node.child1());
- m_jit.storeDouble(value.fpr(), JITCompiler::addressFor(node.local()));
- noResult(m_compileIndex);
- // Indicate that it's no longer necessary to retrieve the value of
- // this bytecode variable from registers or other locations in the register file,
- // but that it is stored as a double.
- valueSourceReferenceForOperand(node.local()) = ValueSource(DoubleInRegisterFile);
- } else {
+ if (!m_jit.graph().isCaptured(node.local())) {
+ if (node.variableAccessData()->shouldUseDoubleFormat()) {
+ SpeculateDoubleOperand value(this, node.child1());
+ m_jit.storeDouble(value.fpr(), JITCompiler::addressFor(node.local()));
+ noResult(m_compileIndex);
+ // Indicate that it's no longer necessary to retrieve the value of
+ // this bytecode variable from registers or other locations in the register file,
+ // but that it is stored as a double.
+ valueSourceReferenceForOperand(node.local()) = ValueSource(DoubleInRegisterFile);
+ break;
+ }
+
PredictedType predictedType = node.variableAccessData()->prediction();
if (isInt32Prediction(predictedType)) {
SpeculateIntegerOperand value(this, node.child1());
m_jit.store32(value.gpr(), JITCompiler::payloadFor(node.local()));
noResult(m_compileIndex);
- } else if (isArrayPrediction(predictedType)) {
+ valueSourceReferenceForOperand(node.local()) = ValueSource(Int32InRegisterFile);
+ break;
+ }
+ if (isArrayPrediction(predictedType)) {
SpeculateCellOperand cell(this, node.child1());
GPRReg cellGPR = cell.gpr();
if (!isArrayPrediction(m_state.forNode(node.child1()).m_type))
speculationCheck(BadType, JSValueRegs(cellGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(cellGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info)));
m_jit.storePtr(cellGPR, JITCompiler::addressFor(node.local()));
noResult(m_compileIndex);
- } else if (isByteArrayPrediction(predictedType)) {
+ valueSourceReferenceForOperand(node.local()) = ValueSource(CellInRegisterFile);
+ break;
+ }
+ if (isByteArrayPrediction(predictedType)) {
SpeculateCellOperand cell(this, node.child1());
GPRReg cellGPR = cell.gpr();
if (!isByteArrayPrediction(m_state.forNode(node.child1()).m_type))
speculationCheck(BadType, JSValueRegs(cellGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(cellGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSByteArray::s_info)));
m_jit.storePtr(cellGPR, JITCompiler::addressFor(node.local()));
noResult(m_compileIndex);
- } else if (isBooleanPrediction(predictedType)) {
+ valueSourceReferenceForOperand(node.local()) = ValueSource(CellInRegisterFile);
+ break;
+ }
+ if (isBooleanPrediction(predictedType)) {
SpeculateBooleanOperand boolean(this, node.child1());
m_jit.storePtr(boolean.gpr(), JITCompiler::addressFor(node.local()));
noResult(m_compileIndex);
- } else {
- JSValueOperand value(this, node.child1());
- m_jit.storePtr(value.gpr(), JITCompiler::addressFor(node.local()));
- noResult(m_compileIndex);
+ valueSourceReferenceForOperand(node.local()) = ValueSource(BooleanInRegisterFile);
+ break;
}
-
- // Indicate that it's no longer necessary to retrieve the value of
- // this bytecode variable from registers or other locations in the register file.
- valueSourceReferenceForOperand(node.local()) = ValueSource::forPrediction(predictedType);
}
+
+ JSValueOperand value(this, node.child1());
+ m_jit.storePtr(value.gpr(), JITCompiler::addressFor(node.local()));
+ noResult(m_compileIndex);
+
+ valueSourceReferenceForOperand(node.local()) = ValueSource(ValueInRegisterFile);
break;
}
@@ -1942,6 +1974,10 @@ void SpeculativeJIT::compile(Node& node)
compileArithSub(node);
break;
+ case ArithNegate:
+ compileArithNegate(node);
+ break;
+
case ArithMul:
compileArithMul(node);
break;
@@ -2007,7 +2043,7 @@ void SpeculativeJIT::compile(Node& node)
case ArithAbs: {
if (at(node.child1()).shouldSpeculateInteger() && node.canSpeculateInteger()) {
SpeculateIntegerOperand op1(this, node.child1());
- GPRTemporary result(this, op1);
+ GPRTemporary result(this);
GPRTemporary scratch(this);
m_jit.zeroExtend32ToPtr(op1.gpr(), result.gpr());
@@ -2389,7 +2425,7 @@ void SpeculativeJIT::compile(Node& node)
// Code to handle put beyond array bounds.
silentSpillAllRegisters(scratchReg);
- callOperation(operationPutByValBeyondArrayBounds, baseReg, propertyReg, valueReg);
+ callOperation(m_jit.codeBlock()->isStrictMode() ? operationPutByValBeyondArrayBoundsStrict : operationPutByValBeyondArrayBoundsNonStrict, baseReg, propertyReg, valueReg);
silentFillAllRegisters(scratchReg);
JITCompiler::Jump wasBeyondArrayBounds = m_jit.jump();
@@ -2549,9 +2585,9 @@ void SpeculativeJIT::compile(Node& node)
m_jit.storePtr(valueGPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
- m_jit.add32(Imm32(1), storageLengthGPR);
+ m_jit.add32(TrustedImm32(1), storageLengthGPR);
m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_length)));
- m_jit.add32(Imm32(1), MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
+ m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
m_jit.orPtr(GPRInfo::tagTypeNumberRegister, storageLengthGPR);
MacroAssembler::Jump done = m_jit.jump();
@@ -2587,7 +2623,7 @@ void SpeculativeJIT::compile(Node& node)
MacroAssembler::Jump emptyArrayCase = m_jit.branchTest32(MacroAssembler::Zero, storageLengthGPR);
- m_jit.sub32(Imm32(1), storageLengthGPR);
+ m_jit.sub32(TrustedImm32(1), storageLengthGPR);
MacroAssembler::Jump slowCase = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(baseGPR, JSArray::vectorLengthOffset()));
@@ -2598,7 +2634,7 @@ void SpeculativeJIT::compile(Node& node)
MacroAssembler::Jump holeCase = m_jit.branchTestPtr(MacroAssembler::Zero, valueGPR);
m_jit.storePtr(MacroAssembler::TrustedImmPtr(0), MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
- m_jit.sub32(MacroAssembler::Imm32(1), MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
+ m_jit.sub32(MacroAssembler::TrustedImm32(1), MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
MacroAssembler::JumpList done;
@@ -3358,9 +3394,9 @@ void SpeculativeJIT::compile(Node& node)
break;
}
- case Phi:
case Flush:
- ASSERT_NOT_REACHED();
+ case Phi:
+ break;
case Breakpoint:
#if ENABLE(DEBUG_WITH_BREAKPOINT)
@@ -3434,6 +3470,73 @@ void SpeculativeJIT::compile(Node& node)
jsValueResult(resultGPR, m_compileIndex);
break;
}
+
+ case CreateActivation: {
+ JSValueOperand value(this, node.child1());
+ GPRTemporary result(this, value);
+
+ GPRReg valueGPR = value.gpr();
+ GPRReg resultGPR = result.gpr();
+
+ m_jit.move(valueGPR, resultGPR);
+
+ JITCompiler::Jump alreadyCreated = m_jit.branchTestPtr(JITCompiler::NonZero, resultGPR);
+
+ silentSpillAllRegisters(resultGPR);
+ callOperation(operationCreateActivation, resultGPR);
+ silentFillAllRegisters(resultGPR);
+
+ alreadyCreated.link(&m_jit);
+
+ cellResult(resultGPR, m_compileIndex);
+ break;
+ }
+
+ case TearOffActivation: {
+ JSValueOperand value(this, node.child1());
+ GPRReg valueGPR = value.gpr();
+
+ JITCompiler::Jump notCreated = m_jit.branchTestPtr(JITCompiler::Zero, valueGPR);
+
+ silentSpillAllRegisters(InvalidGPRReg);
+ callOperation(operationTearOffActivation, valueGPR);
+ silentFillAllRegisters(InvalidGPRReg);
+
+ notCreated.link(&m_jit);
+
+ noResult(m_compileIndex);
+ break;
+ }
+
+ case NewFunctionNoCheck:
+ compileNewFunctionNoCheck(node);
+ break;
+
+ case NewFunction: {
+ JSValueOperand value(this, node.child1());
+ GPRTemporary result(this, value);
+
+ GPRReg valueGPR = value.gpr();
+ GPRReg resultGPR = result.gpr();
+
+ m_jit.move(valueGPR, resultGPR);
+
+ JITCompiler::Jump alreadyCreated = m_jit.branchTestPtr(JITCompiler::NonZero, resultGPR);
+
+ silentSpillAllRegisters(resultGPR);
+ callOperation(
+ operationNewFunction, resultGPR, m_jit.codeBlock()->functionDecl(node.functionDeclIndex()));
+ silentFillAllRegisters(resultGPR);
+
+ alreadyCreated.link(&m_jit);
+
+ cellResult(resultGPR, m_compileIndex);
+ break;
+ }
+
+ case NewFunctionExpression:
+ compileNewFunctionExpression(node);
+ break;
case ForceOSRExit: {
terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
@@ -3449,6 +3552,10 @@ void SpeculativeJIT::compile(Node& node)
case Nop:
ASSERT_NOT_REACHED();
break;
+
+ case LastNodeType:
+ ASSERT_NOT_REACHED();
+ break;
}
if (!m_compileOkay)
diff --git a/Source/JavaScriptCore/dfg/DFGVirtualRegisterAllocationPhase.cpp b/Source/JavaScriptCore/dfg/DFGVirtualRegisterAllocationPhase.cpp
index c0b9fae65..255003612 100644
--- a/Source/JavaScriptCore/dfg/DFGVirtualRegisterAllocationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGVirtualRegisterAllocationPhase.cpp
@@ -48,39 +48,62 @@ public:
dataLog("\n");
#endif
ScoreBoard scoreBoard(m_graph, m_graph.m_preservedVars);
- unsigned sizeExcludingPhiNodes = m_graph.m_blocks.last()->end;
- for (size_t i = 0; i < sizeExcludingPhiNodes; ++i) {
- Node& node = m_graph[i];
-
- if (!node.shouldGenerate())
- continue;
+ scoreBoard.assertClear();
+#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
+ bool needsNewLine = false;
+#endif
+ for (size_t blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
+ BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+ for (size_t indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
+ NodeIndex nodeIndex = block->at(indexInBlock);
+#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
+ if (needsNewLine)
+ dataLog("\n");
+ dataLog(" @%u:", nodeIndex);
+ needsNewLine = true;
+#endif
+ Node& node = m_graph[nodeIndex];
- // GetLocal nodes are effectively phi nodes in the graph, referencing
- // results from prior blocks.
- if (node.op != GetLocal) {
- // First, call use on all of the current node's children, then
- // allocate a VirtualRegister for this node. We do so in this
- // order so that if a child is on its last use, and a
- // VirtualRegister is freed, then it may be reused for node.
- if (node.op & NodeHasVarArgs) {
- for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); childIdx++)
- scoreBoard.use(m_graph.m_varArgChildren[childIdx]);
- } else {
- scoreBoard.use(node.child1());
- scoreBoard.use(node.child2());
- scoreBoard.use(node.child3());
+ if (!node.shouldGenerate() || node.op == Phi || node.op == Flush)
+ continue;
+
+ // GetLocal nodes are effectively phi nodes in the graph, referencing
+ // results from prior blocks.
+ if (node.op != GetLocal) {
+ // First, call use on all of the current node's children, then
+ // allocate a VirtualRegister for this node. We do so in this
+ // order so that if a child is on its last use, and a
+ // VirtualRegister is freed, then it may be reused for node.
+ if (node.flags & NodeHasVarArgs) {
+ for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); childIdx++)
+ scoreBoard.use(m_graph.m_varArgChildren[childIdx]);
+ } else {
+ scoreBoard.use(node.child1());
+ scoreBoard.use(node.child2());
+ scoreBoard.use(node.child3());
+ }
}
- }
- if (!node.hasResult())
- continue;
+ if (!node.hasResult())
+ continue;
- node.setVirtualRegister(scoreBoard.allocate());
- // 'mustGenerate' nodes have their useCount artificially elevated,
- // call use now to account for this.
- if (node.mustGenerate())
- scoreBoard.use(i);
+ VirtualRegister virtualRegister = scoreBoard.allocate();
+#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
+ dataLog(" Assigning virtual register %u to node %u.",
+ virtualRegister, nodeIndex);
+#endif
+ node.setVirtualRegister(virtualRegister);
+ // 'mustGenerate' nodes have their useCount artificially elevated,
+ // call use now to account for this.
+ if (node.mustGenerate())
+ scoreBoard.use(nodeIndex);
+ }
+ scoreBoard.assertClear();
}
+#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
+ if (needsNewLine)
+ dataLog("\n");
+#endif
// 'm_numCalleeRegisters' is the number of locals and temporaries allocated
// for the function (and checked for on entry). Since we perform a new and
diff --git a/Source/JavaScriptCore/heap/CopiedAllocator.h b/Source/JavaScriptCore/heap/CopiedAllocator.h
index c5ba50d78..dc3c5dfed 100644
--- a/Source/JavaScriptCore/heap/CopiedAllocator.h
+++ b/Source/JavaScriptCore/heap/CopiedAllocator.h
@@ -31,6 +31,7 @@
namespace JSC {
class CopiedAllocator {
+ friend class JIT;
public:
CopiedAllocator();
void* allocate(size_t);
@@ -93,7 +94,7 @@ inline void CopiedAllocator::resetCurrentBlock(CopiedBlock* newBlock)
inline size_t CopiedAllocator::currentUtilization()
{
- return static_cast<size_t>(m_currentOffset - m_currentBlock->m_payload);
+ return static_cast<size_t>(m_currentOffset - m_currentBlock->payload());
}
inline void CopiedAllocator::resetLastAllocation(void* ptr)
diff --git a/Source/JavaScriptCore/heap/CopiedBlock.h b/Source/JavaScriptCore/heap/CopiedBlock.h
index a57c1150c..387b2ddab 100644
--- a/Source/JavaScriptCore/heap/CopiedBlock.h
+++ b/Source/JavaScriptCore/heap/CopiedBlock.h
@@ -40,26 +40,29 @@ class CopiedBlock : public HeapBlock {
public:
CopiedBlock(PageAllocationAligned& allocation)
: HeapBlock(allocation)
- , m_offset(m_payload)
+ , m_offset(payload())
, m_isPinned(false)
{
- ASSERT(is8ByteAligned(static_cast<void*>(m_payload)));
+ ASSERT(is8ByteAligned(static_cast<void*>(m_offset)));
#if USE(JSVALUE64)
- memset(static_cast<void*>(m_payload), 0, static_cast<size_t>((reinterpret_cast<char*>(this) + allocation.size()) - m_payload));
+ char* offset = static_cast<char*>(m_offset);
+ memset(static_cast<void*>(offset), 0, static_cast<size_t>((reinterpret_cast<char*>(this) + allocation.size()) - offset));
#else
JSValue emptyValue;
- JSValue* limit = reinterpret_cast<JSValue*>(reinterpret_cast<char*>(this) + allocation.size());
- for (JSValue* currentValue = reinterpret_cast<JSValue*>(m_payload); currentValue < limit; currentValue++)
+ JSValue* limit = reinterpret_cast_ptr<JSValue*>(reinterpret_cast<char*>(this) + allocation.size());
+ for (JSValue* currentValue = reinterpret_cast<JSValue*>(m_offset); currentValue < limit; currentValue++)
*currentValue = emptyValue;
#endif
}
+ char* payload()
+ {
+ return reinterpret_cast<char*>(this) + ((sizeof(CopiedBlock) + 7) & ~7);
+ }
+
private:
void* m_offset;
uintptr_t m_isPinned;
- uintptr_t m_padding;
- uintptr_t m_dummy;
- char m_payload[1];
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/heap/CopiedSpace.cpp b/Source/JavaScriptCore/heap/CopiedSpace.cpp
index 3310d2c58..c8470120f 100644
--- a/Source/JavaScriptCore/heap/CopiedSpace.cpp
+++ b/Source/JavaScriptCore/heap/CopiedSpace.cpp
@@ -153,7 +153,7 @@ void CopiedSpace::doneFillingBlock(CopiedBlock* block)
ASSERT(block->m_offset < reinterpret_cast<char*>(block) + HeapBlock::s_blockSize);
ASSERT(m_inCopyingPhase);
- if (block->m_offset == block->m_payload) {
+ if (block->m_offset == block->payload()) {
recycleBlock(block);
return;
}
@@ -167,7 +167,7 @@ void CopiedSpace::doneFillingBlock(CopiedBlock* block)
{
MutexLocker locker(m_memoryStatsLock);
- m_totalMemoryUtilized += static_cast<size_t>(static_cast<char*>(block->m_offset) - block->m_payload);
+ m_totalMemoryUtilized += static_cast<size_t>(static_cast<char*>(block->m_offset) - block->payload());
}
{
diff --git a/Source/JavaScriptCore/heap/CopiedSpace.h b/Source/JavaScriptCore/heap/CopiedSpace.h
index 285e2b9a2..e8fa80055 100644
--- a/Source/JavaScriptCore/heap/CopiedSpace.h
+++ b/Source/JavaScriptCore/heap/CopiedSpace.h
@@ -46,6 +46,7 @@ class HeapBlock;
class CopiedSpace {
friend class SlotVisitor;
+ friend class JIT;
public:
CopiedSpace(Heap*);
void init();
@@ -53,6 +54,8 @@ public:
CheckedBoolean tryAllocate(size_t, void**);
CheckedBoolean tryReallocate(void**, size_t, size_t);
+ CopiedAllocator& allocator() { return m_allocator; }
+
void startedCopying();
void doneCopying();
bool isInCopyPhase() { return m_inCopyingPhase; }
diff --git a/Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h b/Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h
index 9a1f63cec..0b1b38d32 100644
--- a/Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h
+++ b/Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h
@@ -92,7 +92,7 @@ inline CheckedBoolean CopiedSpace::borrowBlock(CopiedBlock** outBlock)
MutexLocker locker(m_loanedBlocksLock);
m_numberOfLoanedBlocks++;
- ASSERT(block->m_offset == block->m_payload);
+ ASSERT(block->m_offset == block->payload());
*outBlock = block;
return true;
}
@@ -151,9 +151,9 @@ inline void* CopiedSpace::allocateFromBlock(CopiedBlock* block, size_t bytes)
ASSERT(is8ByteAligned(block->m_offset));
void* ptr = block->m_offset;
- ASSERT(block->m_offset >= block->m_payload && block->m_offset < reinterpret_cast<char*>(block) + HeapBlock::s_blockSize);
+ ASSERT(block->m_offset >= block->payload() && block->m_offset < reinterpret_cast<char*>(block) + HeapBlock::s_blockSize);
block->m_offset = static_cast<void*>((static_cast<char*>(ptr) + bytes));
- ASSERT(block->m_offset >= block->m_payload && block->m_offset < reinterpret_cast<char*>(block) + HeapBlock::s_blockSize);
+ ASSERT(block->m_offset >= block->payload() && block->m_offset < reinterpret_cast<char*>(block) + HeapBlock::s_blockSize);
ASSERT(is8ByteAligned(ptr));
return ptr;
diff --git a/Source/JavaScriptCore/heap/DFGCodeBlocks.cpp b/Source/JavaScriptCore/heap/DFGCodeBlocks.cpp
index 03c8df2ff..f0d7c0c89 100644
--- a/Source/JavaScriptCore/heap/DFGCodeBlocks.cpp
+++ b/Source/JavaScriptCore/heap/DFGCodeBlocks.cpp
@@ -67,8 +67,10 @@ void DFGCodeBlocks::jettison(PassOwnPtr<CodeBlock> codeBlockPtr)
void DFGCodeBlocks::clearMarks()
{
- for (HashSet<CodeBlock*>::iterator iter = m_set.begin(); iter != m_set.end(); ++iter)
+ for (HashSet<CodeBlock*>::iterator iter = m_set.begin(); iter != m_set.end(); ++iter) {
(*iter)->m_dfgData->mayBeExecuting = false;
+ (*iter)->m_dfgData->visitAggregateHasBeenCalled = false;
+ }
}
void DFGCodeBlocks::deleteUnmarkedJettisonedCodeBlocks()
diff --git a/Source/JavaScriptCore/heap/GCAssertions.h b/Source/JavaScriptCore/heap/GCAssertions.h
index f044df6f0..9feefe1d1 100644
--- a/Source/JavaScriptCore/heap/GCAssertions.h
+++ b/Source/JavaScriptCore/heap/GCAssertions.h
@@ -26,7 +26,7 @@
#ifndef GCAssertions_h
#define GCAssertions_h
-#include "Assertions.h"
+#include <wtf/Assertions.h>
#if ENABLE(GC_VALIDATION)
#define ASSERT_GC_OBJECT_LOOKS_VALID(cell) do { \
diff --git a/Source/JavaScriptCore/heap/HandleHeap.h b/Source/JavaScriptCore/heap/HandleHeap.h
index 3b9db37a2..c9ee11b2f 100644
--- a/Source/JavaScriptCore/heap/HandleHeap.h
+++ b/Source/JavaScriptCore/heap/HandleHeap.h
@@ -26,11 +26,11 @@
#ifndef HandleHeap_h
#define HandleHeap_h
-#include "BlockStack.h"
+#include <wtf/BlockStack.h>
#include "Handle.h"
-#include "HashCountedSet.h"
-#include "SentinelLinkedList.h"
-#include "SinglyLinkedList.h"
+#include <wtf/HashCountedSet.h>
+#include <wtf/SentinelLinkedList.h>
+#include <wtf/SinglyLinkedList.h>
namespace JSC {
diff --git a/Source/JavaScriptCore/heap/HandleStack.h b/Source/JavaScriptCore/heap/HandleStack.h
index a1e8a0b2a..858ebf23f 100644
--- a/Source/JavaScriptCore/heap/HandleStack.h
+++ b/Source/JavaScriptCore/heap/HandleStack.h
@@ -26,8 +26,8 @@
#ifndef HandleStack_h
#define HandleStack_h
-#include "Assertions.h"
-#include "BlockStack.h"
+#include <wtf/Assertions.h>
+#include <wtf/BlockStack.h>
#include "Handle.h"
#include <wtf/UnusedParam.h>
diff --git a/Source/JavaScriptCore/heap/Heap.cpp b/Source/JavaScriptCore/heap/Heap.cpp
index 1333c7b2c..a5d4a063f 100644
--- a/Source/JavaScriptCore/heap/Heap.cpp
+++ b/Source/JavaScriptCore/heap/Heap.cpp
@@ -328,6 +328,7 @@ Heap::Heap(JSGlobalData* globalData, HeapSize heapSize)
, m_handleHeap(globalData)
, m_isSafeToCollect(false)
, m_globalData(globalData)
+ , m_lastGCLength(0)
{
(*m_activityCallback)();
m_numberOfFreeBlocks = 0;
@@ -781,6 +782,7 @@ void Heap::collect(SweepToggle sweepToggle)
ASSERT(globalData()->identifierTable == wtfThreadData().currentIdentifierTable());
ASSERT(m_isSafeToCollect);
JAVASCRIPTCORE_GC_BEGIN();
+ double lastGCStartTime = WTF::currentTime();
#if ENABLE(GGC)
bool fullGC = sweepToggle == DoSweep;
if (!fullGC)
@@ -835,6 +837,8 @@ void Heap::collect(SweepToggle sweepToggle)
m_lastFullGCSize = newSize;
setHighWaterMark(max(proportionalBytes, m_minBytesPerCycle));
}
+ double lastGCEndTime = WTF::currentTime();
+ m_lastGCLength = lastGCEndTime - lastGCStartTime;
JAVASCRIPTCORE_GC_END();
(*m_activityCallback)();
diff --git a/Source/JavaScriptCore/heap/Heap.h b/Source/JavaScriptCore/heap/Heap.h
index bcacee6d5..09a95882b 100644
--- a/Source/JavaScriptCore/heap/Heap.h
+++ b/Source/JavaScriptCore/heap/Heap.h
@@ -99,6 +99,7 @@ namespace JSC {
MarkedAllocator& firstAllocatorWithoutDestructors() { return m_objectSpace.firstAllocator(); }
MarkedAllocator& allocatorForObjectWithoutDestructor(size_t bytes) { return m_objectSpace.allocatorFor(bytes); }
MarkedAllocator& allocatorForObjectWithDestructor(size_t bytes) { return m_objectSpace.destructorAllocatorFor(bytes); }
+ CopiedAllocator& storageAllocator() { return m_storageSpace.allocator(); }
CheckedBoolean tryAllocateStorage(size_t, void**);
CheckedBoolean tryReallocateStorage(void**, size_t, size_t);
@@ -137,6 +138,8 @@ namespace JSC {
void getConservativeRegisterRoots(HashSet<JSCell*>& roots);
+ double lastGCLength() { return m_lastGCLength; }
+
private:
friend class CodeBlock;
friend class LLIntOffsetsExtractor;
@@ -235,6 +238,7 @@ namespace JSC {
bool m_isSafeToCollect;
JSGlobalData* m_globalData;
+ double m_lastGCLength;
};
bool Heap::isBusy()
diff --git a/Source/JavaScriptCore/heap/MarkedBlock.h b/Source/JavaScriptCore/heap/MarkedBlock.h
index 5f70b69d4..3d0182eb8 100644
--- a/Source/JavaScriptCore/heap/MarkedBlock.h
+++ b/Source/JavaScriptCore/heap/MarkedBlock.h
@@ -321,6 +321,8 @@ namespace JSC {
return false;
if ((atomNumber - firstAtom) % m_atomsPerCell) // Filters pointers into cell middles.
return false;
+ if (atomNumber >= m_endAtom) // Filters pointers into invalid cells out of the range.
+ return false;
return isLive(static_cast<const JSCell*>(p));
}
diff --git a/Source/JavaScriptCore/heap/MarkedSpace.h b/Source/JavaScriptCore/heap/MarkedSpace.h
index cfcf3f8dc..b553eb1b1 100644
--- a/Source/JavaScriptCore/heap/MarkedSpace.h
+++ b/Source/JavaScriptCore/heap/MarkedSpace.h
@@ -26,7 +26,7 @@
#include "MarkedAllocator.h"
#include "MarkedBlock.h"
#include "MarkedBlockSet.h"
-#include "PageAllocationAligned.h"
+#include <wtf/PageAllocationAligned.h>
#include <wtf/Bitmap.h>
#include <wtf/DoublyLinkedList.h>
#include <wtf/FixedArray.h>
diff --git a/Source/JavaScriptCore/heap/PassWeak.h b/Source/JavaScriptCore/heap/PassWeak.h
index b7aa7b10d..0d86e6c65 100644
--- a/Source/JavaScriptCore/heap/PassWeak.h
+++ b/Source/JavaScriptCore/heap/PassWeak.h
@@ -26,10 +26,10 @@
#ifndef PassWeak_h
#define PassWeak_h
-#include "Assertions.h"
+#include <wtf/Assertions.h>
#include "Handle.h"
-#include "NullPtr.h"
-#include "TypeTraits.h"
+#include <wtf/NullPtr.h>
+#include <wtf/TypeTraits.h>
namespace JSC {
diff --git a/Source/JavaScriptCore/heap/Strong.h b/Source/JavaScriptCore/heap/Strong.h
index a9389fa53..d2f2a2278 100644
--- a/Source/JavaScriptCore/heap/Strong.h
+++ b/Source/JavaScriptCore/heap/Strong.h
@@ -26,7 +26,7 @@
#ifndef Strong_h
#define Strong_h
-#include "Assertions.h"
+#include <wtf/Assertions.h>
#include "Handle.h"
#include "HandleHeap.h"
diff --git a/Source/JavaScriptCore/heap/Weak.h b/Source/JavaScriptCore/heap/Weak.h
index 96fe1b58c..8291e4440 100644
--- a/Source/JavaScriptCore/heap/Weak.h
+++ b/Source/JavaScriptCore/heap/Weak.h
@@ -26,7 +26,7 @@
#ifndef Weak_h
#define Weak_h
-#include "Assertions.h"
+#include <wtf/Assertions.h>
#include "Handle.h"
#include "HandleHeap.h"
#include "JSGlobalData.h"
diff --git a/Source/JavaScriptCore/interpreter/Interpreter.cpp b/Source/JavaScriptCore/interpreter/Interpreter.cpp
index 336f109c0..a74d3de89 100644
--- a/Source/JavaScriptCore/interpreter/Interpreter.cpp
+++ b/Source/JavaScriptCore/interpreter/Interpreter.cpp
@@ -44,6 +44,7 @@
#include "GetterSetter.h"
#include "JSActivation.h"
#include "JSArray.h"
+#include "JSBoundFunction.h"
#include "JSByteArray.h"
#include "JSNotAnObject.h"
#include "JSPropertyNameIterator.h"
@@ -559,31 +560,27 @@ void Interpreter::initialize(LLInt::Data* llintData, bool canUseJIT)
{
UNUSED_PARAM(llintData);
UNUSED_PARAM(canUseJIT);
-#if ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER) || ENABLE(LLINT)
-#if !ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
- // Having LLInt enabled, but not being able to use the JIT, and not having
- // a computed goto interpreter, is not supported. Not because we cannot
- // support it, but because I decided to draw the line at the number of
- // permutations of execution engines that I wanted this code to grok.
- ASSERT(canUseJIT);
+
+ // If we have LLInt, then we shouldn't be building any kind of classic interpreter.
+#if ENABLE(LLINT) && ENABLE(CLASSIC_INTERPRETER)
+#error "Building both LLInt and the Classic Interpreter is not supported because it doesn't make sense."
#endif
- if (canUseJIT) {
+
#if ENABLE(LLINT)
- m_opcodeTable = llintData->opcodeMap();
- for (int i = 0; i < numOpcodeIDs; ++i)
- m_opcodeIDTable.add(m_opcodeTable[i], static_cast<OpcodeID>(i));
-#else
+ m_opcodeTable = llintData->opcodeMap();
+ for (int i = 0; i < numOpcodeIDs; ++i)
+ m_opcodeIDTable.add(m_opcodeTable[i], static_cast<OpcodeID>(i));
+ m_classicEnabled = false;
+#elif ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
+ if (canUseJIT) {
// If the JIT is present, don't use jump destinations for opcodes.
for (int i = 0; i < numOpcodeIDs; ++i) {
Opcode opcode = bitwise_cast<void*>(static_cast<uintptr_t>(i));
m_opcodeTable[i] = opcode;
}
-#endif
+ m_classicEnabled = false;
} else {
-#if ENABLE(LLINT)
- m_opcodeTable = new Opcode[numOpcodeIDs];
-#endif
privateExecute(InitializeAndReturn, 0, 0);
for (int i = 0; i < numOpcodeIDs; ++i)
@@ -817,13 +814,14 @@ static void appendSourceToError(CallFrame* callFrame, ErrorInstance* exception,
exception->putDirect(*globalData, globalData->propertyNames->message, jsString(globalData, message));
}
-static int getLineNumberForCallFrame(CallFrame* callFrame)
+static int getLineNumberForCallFrame(JSGlobalData* globalData, CallFrame* callFrame)
{
+ UNUSED_PARAM(globalData);
callFrame = callFrame->removeHostCallFrameFlag();
CodeBlock* codeBlock = callFrame->codeBlock();
if (!codeBlock)
return -1;
-#if ENABLE(INTERPRETER)
+#if ENABLE(CLASSIC_INTERPRETER)
if (!globalData->canUseJIT())
return codeBlock->lineNumberForBytecodeOffset(callFrame->bytecodeOffsetForNonDFGCode() - 1);
#endif
@@ -833,6 +831,8 @@ static int getLineNumberForCallFrame(CallFrame* callFrame)
return codeBlock->lineNumberForBytecodeOffset(codeBlock->codeOrigin(callFrame->codeOriginIndexForDFG()).bytecodeIndex);
#endif
return codeBlock->lineNumberForBytecodeOffset(callFrame->bytecodeOffsetForNonDFGCode());
+#else
+ return -1;
#endif
}
@@ -842,19 +842,28 @@ static CallFrame* getCallerInfo(JSGlobalData* globalData, CallFrame* callFrame,
unsigned bytecodeOffset = 0;
lineNumber = -1;
ASSERT(!callFrame->hasHostCallFrameFlag());
- CallFrame* callerFrame = callFrame->codeBlock() ? callFrame->trueCallerFrame() : 0;
+ CallFrame* callerFrame = callFrame->codeBlock() ? callFrame->trueCallerFrame() : callFrame->callerFrame()->removeHostCallFrameFlag();
bool callframeIsHost = callerFrame->addHostCallFrameFlag() == callFrame->callerFrame();
ASSERT(!callerFrame->hasHostCallFrameFlag());
if (callerFrame == CallFrame::noCaller() || !callerFrame || !callerFrame->codeBlock())
return callerFrame;
-
+
CodeBlock* callerCodeBlock = callerFrame->codeBlock();
+
+#if ENABLE(JIT)
+ if (!callFrame->hasReturnPC())
+ callframeIsHost = true;
+#endif
+#if ENABLE(DFG_JIT)
+ if (callFrame->isInlineCallFrame())
+ callframeIsHost = false;
+#endif
if (callframeIsHost) {
// Don't need to deal with inline callframes here as by definition we haven't
// inlined a call with an intervening native call frame.
-#if ENABLE(INTERPRETER)
+#if ENABLE(CLASSIC_INTERPRETER)
if (!globalData->canUseJIT()) {
bytecodeOffset = callerFrame->bytecodeOffsetForNonDFGCode();
lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset - 1);
@@ -863,14 +872,15 @@ static CallFrame* getCallerInfo(JSGlobalData* globalData, CallFrame* callFrame,
#endif
#if ENABLE(JIT)
#if ENABLE(DFG_JIT)
- if (callerCodeBlock && callerCodeBlock->getJITType() == JITCode::DFGJIT)
- bytecodeOffset = callerCodeBlock->codeOrigin(callerFrame->codeOriginIndexForDFG()).bytecodeIndex;
- else
+ if (callerCodeBlock && callerCodeBlock->getJITType() == JITCode::DFGJIT) {
+ unsigned codeOriginIndex = callerFrame->codeOriginIndexForDFG();
+ bytecodeOffset = callerCodeBlock->codeOrigin(codeOriginIndex).bytecodeIndex;
+ } else
#endif
bytecodeOffset = callerFrame->bytecodeOffsetForNonDFGCode();
#endif
} else {
-#if ENABLE(INTERPRETER)
+#if ENABLE(CLASSIC_INTERPRETER)
if (!globalData->canUseJIT()) {
bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnVPC());
lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset - 1);
@@ -914,7 +924,7 @@ static CallFrame* getCallerInfo(JSGlobalData* globalData, CallFrame* callFrame,
static ALWAYS_INLINE const UString getSourceURLFromCallFrame(CallFrame* callFrame)
{
ASSERT(!callFrame->hasHostCallFrameFlag());
-#if ENABLE(INTERPRETER)
+#if ENABLE(CLASSIC_INTERPRETER)
#if ENABLE(JIT)
if (callFrame->globalData().canUseJIT())
return callFrame->codeBlock()->ownerExecutable()->sourceURL();
@@ -949,8 +959,8 @@ void Interpreter::getStackTrace(JSGlobalData* globalData, int line, Vector<Stack
return;
if (line == -1)
- line = getLineNumberForCallFrame(callFrame);
-
+ line = getLineNumberForCallFrame(globalData, callFrame);
+
while (callFrame && callFrame != CallFrame::noCaller()) {
UString sourceURL;
if (callFrame->codeBlock()) {
@@ -1144,7 +1154,7 @@ JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, S
break;
}
case JSONPPathEntryTypeLookup: {
- baseObject.put(callFrame, JSONPPath.last().m_pathIndex, JSONPValue);
+ baseObject.putByIndex(callFrame, JSONPPath.last().m_pathIndex, JSONPValue, slot.isStrictMode());
if (callFrame->hadException())
return jsUndefined();
break;
@@ -1184,7 +1194,7 @@ failedJSONP:
m_reentryDepth++;
#if ENABLE(JIT)
- if (callFrame->globalData().canUseJIT())
+ if (!classicEnabled())
result = program->generatedJITCode().execute(&m_registerFile, newCallFrame, scopeChain->globalData);
else
#endif
@@ -1256,7 +1266,7 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
m_reentryDepth++;
#if ENABLE(JIT)
- if (callFrame->globalData().canUseJIT())
+ if (!classicEnabled())
result = callData.js.functionExecutable->generatedJITCodeForCall().execute(&m_registerFile, newCallFrame, callDataScopeChain->globalData);
else
#endif
@@ -1352,7 +1362,7 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
m_reentryDepth++;
#if ENABLE(JIT)
- if (callFrame->globalData().canUseJIT())
+ if (!classicEnabled())
result = constructData.js.functionExecutable->generatedJITCodeForConstruct().execute(&m_registerFile, newCallFrame, constructDataScopeChain->globalData);
else
#endif
@@ -2567,24 +2577,6 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
vPC += OPCODE_LENGTH(op_bitor);
NEXT_INSTRUCTION();
}
- DEFINE_OPCODE(op_bitnot) {
- /* bitnot dst(r) src(r)
-
- Computes bitwise NOT of register src1 (converted to int32),
- and puts the result in register dst.
- */
- int dst = vPC[1].u.operand;
- JSValue src = callFrame->r(vPC[2].u.operand).jsValue();
- if (src.isInt32())
- callFrame->uncheckedR(dst) = jsNumber(~src.asInt32());
- else {
- JSValue result = jsNumber(~src.toInt32(callFrame));
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = result;
- }
- vPC += OPCODE_LENGTH(op_bitnot);
- NEXT_INSTRUCTION();
- }
DEFINE_OPCODE(op_not) {
/* not dst(r) src(r)
@@ -3785,7 +3777,7 @@ skip_id_custom_self:
if (jsArray->canSetIndex(i))
jsArray->setIndex(*globalData, i, callFrame->r(value).jsValue());
else
- jsArray->JSArray::putByIndex(jsArray, callFrame, i, callFrame->r(value).jsValue());
+ jsArray->JSArray::putByIndex(jsArray, callFrame, i, callFrame->r(value).jsValue(), codeBlock->isStrictMode());
} else if (isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
JSByteArray* jsByteArray = asByteArray(baseValue);
JSValue jsValue = callFrame->r(value).jsValue();
@@ -3794,9 +3786,9 @@ skip_id_custom_self:
else if (jsValue.isDouble())
jsByteArray->setIndex(i, jsValue.asDouble());
else
- baseValue.put(callFrame, i, jsValue);
+ baseValue.putByIndex(callFrame, i, jsValue, codeBlock->isStrictMode());
} else
- baseValue.put(callFrame, i, callFrame->r(value).jsValue());
+ baseValue.putByIndex(callFrame, i, callFrame->r(value).jsValue(), codeBlock->isStrictMode());
} else {
Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
if (!globalData->exception) { // Don't put to an object if toString threw an exception.
@@ -3859,7 +3851,9 @@ skip_id_custom_self:
unsigned property = vPC[2].u.operand;
int value = vPC[3].u.operand;
- callFrame->r(base).jsValue().put(callFrame, property, callFrame->r(value).jsValue());
+ JSValue arrayValue = callFrame->r(base).jsValue();
+ ASSERT(isJSArray(arrayValue));
+ asArray(arrayValue)->putDirectIndex(callFrame, property, callFrame->r(value).jsValue(), false);
vPC += OPCODE_LENGTH(op_put_by_index);
NEXT_INSTRUCTION();
@@ -5316,18 +5310,29 @@ JSValue Interpreter::retrieveArgumentsFromVMCode(CallFrame* callFrame, JSFunctio
JSValue Interpreter::retrieveCallerFromVMCode(CallFrame* callFrame, JSFunction* function) const
{
CallFrame* functionCallFrame = findFunctionCallFrameFromVMCode(callFrame, function);
+
if (!functionCallFrame)
return jsNull();
- if (functionCallFrame->callerFrame()->hasHostCallFrameFlag())
+ int lineNumber;
+ CallFrame* callerFrame = getCallerInfo(&callFrame->globalData(), functionCallFrame, lineNumber);
+ if (!callerFrame)
return jsNull();
-
- CallFrame* callerFrame = functionCallFrame->trueCallerFrame();
-
JSValue caller = callerFrame->callee();
if (!caller)
return jsNull();
+ // Skip over function bindings.
+ ASSERT(caller.isObject());
+ while (asObject(caller)->inherits(&JSBoundFunction::s_info)) {
+ callerFrame = getCallerInfo(&callFrame->globalData(), callerFrame, lineNumber);
+ if (!callerFrame)
+ return jsNull();
+ caller = callerFrame->callee();
+ if (!caller)
+ return jsNull();
+ }
+
return caller;
}
diff --git a/Source/JavaScriptCore/jit/ExecutableAllocator.cpp b/Source/JavaScriptCore/jit/ExecutableAllocator.cpp
index 75137279e..5912f8652 100644
--- a/Source/JavaScriptCore/jit/ExecutableAllocator.cpp
+++ b/Source/JavaScriptCore/jit/ExecutableAllocator.cpp
@@ -29,11 +29,22 @@
#if ENABLE(EXECUTABLE_ALLOCATOR_DEMAND)
#include "CodeProfiling.h"
+#include <wtf/DataLog.h>
+#include <wtf/HashSet.h>
#include <wtf/MetaAllocator.h>
#include <wtf/PageReservation.h>
+#if ENABLE(ASSEMBLER_WX_EXCLUSIVE)
+#include <wtf/PassOwnPtr.h>
+#endif
+#include <wtf/ThreadingPrimitives.h>
#include <wtf/VMTags.h>
#endif
+// Uncomment to create an artificial executable memory usage limit. This limit
+// is imperfect and is primarily useful for testing the VM's ability to handle
+// out-of-executable-memory situations.
+// #define EXECUTABLE_MEMORY_LIMIT 1000000
+
#if ENABLE(ASSEMBLER)
using namespace WTF;
@@ -47,15 +58,48 @@ public:
DemandExecutableAllocator()
: MetaAllocator(32) // round up all allocations to 32 bytes
{
+ MutexLocker lock(allocatorsMutex());
+ allocators().add(this);
// Don't preallocate any memory here.
}
virtual ~DemandExecutableAllocator()
{
+ {
+ MutexLocker lock(allocatorsMutex());
+ allocators().remove(this);
+ }
for (unsigned i = 0; i < reservations.size(); ++i)
reservations.at(i).deallocate();
}
+ static size_t bytesAllocatedByAllAllocators()
+ {
+ size_t total = 0;
+ MutexLocker lock(allocatorsMutex());
+ for (HashSet<DemandExecutableAllocator*>::const_iterator allocator = allocators().begin(); allocator != allocators().end(); ++allocator)
+ total += (*allocator)->bytesAllocated();
+ return total;
+ }
+
+ static size_t bytesCommittedByAllocactors()
+ {
+ size_t total = 0;
+ MutexLocker lock(allocatorsMutex());
+ for (HashSet<DemandExecutableAllocator*>::const_iterator allocator = allocators().begin(); allocator != allocators().end(); ++allocator)
+ total += (*allocator)->bytesCommitted();
+ return total;
+ }
+
+#if ENABLE(META_ALLOCATOR_PROFILE)
+ static void dumpProfileFromAllAllocators()
+ {
+ MutexLocker lock(allocatorsMutex());
+ for (HashSet<DemandExecutableAllocator*>::const_iterator allocator = allocators().begin(); allocator != allocators().end(); ++allocator)
+ (*allocator)->dumpProfile();
+ }
+#endif
+
protected:
virtual void* allocateNewSpace(size_t& numPages)
{
@@ -65,6 +109,11 @@ protected:
numPages = newNumPages;
+#ifdef EXECUTABLE_MEMORY_LIMIT
+ if (bytesAllocatedByAllAllocators() >= EXECUTABLE_MEMORY_LIMIT)
+ return 0;
+#endif
+
PageReservation reservation = PageReservation::reserve(numPages * pageSize(), OSAllocator::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, true);
if (!reservation)
CRASH();
@@ -86,20 +135,50 @@ protected:
private:
Vector<PageReservation, 16> reservations;
+ static HashSet<DemandExecutableAllocator*>& allocators()
+ {
+ DEFINE_STATIC_LOCAL(HashSet<DemandExecutableAllocator*>, sAllocators, ());
+ return sAllocators;
+ }
+ static Mutex& allocatorsMutex()
+ {
+ DEFINE_STATIC_LOCAL(Mutex, mutex, ());
+ return mutex;
+ }
};
-static DemandExecutableAllocator* allocator;
+#if ENABLE(ASSEMBLER_WX_EXCLUSIVE)
+void ExecutableAllocator::initializeAllocator()
+{
+}
+#else
+static DemandExecutableAllocator* gAllocator;
+
+namespace {
+static inline DemandExecutableAllocator* allocator()
+{
+ return gAllocator;
+}
+}
void ExecutableAllocator::initializeAllocator()
{
- ASSERT(!allocator);
- allocator = new DemandExecutableAllocator();
- CodeProfiling::notifyAllocator(allocator);
+ ASSERT(!gAllocator);
+ gAllocator = new DemandExecutableAllocator();
+ CodeProfiling::notifyAllocator(gAllocator);
}
+#endif
ExecutableAllocator::ExecutableAllocator(JSGlobalData&)
+#if ENABLE(ASSEMBLER_WX_EXCLUSIVE)
+ : m_allocator(adoptPtr(new DemandExecutableAllocator()))
+#endif
+{
+ ASSERT(allocator());
+}
+
+ExecutableAllocator::~ExecutableAllocator()
{
- ASSERT(allocator);
}
bool ExecutableAllocator::isValid() const
@@ -109,26 +188,44 @@ bool ExecutableAllocator::isValid() const
bool ExecutableAllocator::underMemoryPressure()
{
+#ifdef EXECUTABLE_MEMORY_LIMIT
+ return DemandExecutableAllocator::bytesAllocatedByAllAllocators() > EXECUTABLE_MEMORY_LIMIT / 2;
+#else
return false;
+#endif
+}
+
+double ExecutableAllocator::memoryPressureMultiplier(size_t addedMemoryUsage)
+{
+#ifdef EXECUTABLE_MEMORY_LIMIT
+ size_t bytesAllocated = DemandExecutableAllocator::bytesAllocatedByAllAllocators() + addedMemoryUsage;
+ if (bytesAllocated >= EXECUTABLE_MEMORY_LIMIT)
+ bytesAllocated = EXECUTABLE_MEMORY_LIMIT;
+ return static_cast<double>(EXECUTABLE_MEMORY_LIMIT) /
+ (EXECUTABLE_MEMORY_LIMIT - bytesAllocated);
+#else
+ UNUSED_PARAM(addedMemoryUsage);
+ return 1.0;
+#endif
}
-PassRefPtr<ExecutableMemoryHandle> ExecutableAllocator::allocate(JSGlobalData&, size_t sizeInBytes, void* ownerUID)
+PassRefPtr<ExecutableMemoryHandle> ExecutableAllocator::allocate(JSGlobalData&, size_t sizeInBytes, void* ownerUID, JITCompilationEffort effort)
{
- RefPtr<ExecutableMemoryHandle> result = allocator->allocate(sizeInBytes, ownerUID);
- if (!result)
+ RefPtr<ExecutableMemoryHandle> result = allocator()->allocate(sizeInBytes, ownerUID);
+ if (!result && effort == JITCompilationMustSucceed)
CRASH();
return result.release();
}
size_t ExecutableAllocator::committedByteCount()
{
- return allocator->bytesCommitted();
+ return DemandExecutableAllocator::bytesCommittedByAllocactors();
}
#if ENABLE(META_ALLOCATOR_PROFILE)
void ExecutableAllocator::dumpProfile()
{
- allocator->dumpProfile();
+ DemandExecutableAllocator::dumpProfileFromAllAllocators();
}
#endif
diff --git a/Source/JavaScriptCore/jit/ExecutableAllocator.h b/Source/JavaScriptCore/jit/ExecutableAllocator.h
index 7520913d0..8a14ac67e 100644
--- a/Source/JavaScriptCore/jit/ExecutableAllocator.h
+++ b/Source/JavaScriptCore/jit/ExecutableAllocator.h
@@ -25,6 +25,7 @@
#ifndef ExecutableAllocator_h
#define ExecutableAllocator_h
+#include "JITCompilationEffort.h"
#include <stddef.h> // for ptrdiff_t
#include <limits>
#include <wtf/Assertions.h>
@@ -95,11 +96,16 @@ typedef WTF::MetaAllocatorHandle ExecutableMemoryHandle;
#if ENABLE(JIT) && ENABLE(ASSEMBLER)
+#if ENABLE(EXECUTABLE_ALLOCATOR_DEMAND)
+class DemandExecutableAllocator;
+#endif
+
class ExecutableAllocator {
enum ProtectionSetting { Writable, Executable };
public:
ExecutableAllocator(JSGlobalData&);
+ ~ExecutableAllocator();
static void initializeAllocator();
@@ -107,13 +113,15 @@ public:
static bool underMemoryPressure();
+ static double memoryPressureMultiplier(size_t addedMemoryUsage);
+
#if ENABLE(META_ALLOCATOR_PROFILE)
static void dumpProfile();
#else
static void dumpProfile() { }
#endif
- PassRefPtr<ExecutableMemoryHandle> allocate(JSGlobalData&, size_t sizeInBytes, void* ownerUID);
+ PassRefPtr<ExecutableMemoryHandle> allocate(JSGlobalData&, size_t sizeInBytes, void* ownerUID, JITCompilationEffort);
#if ENABLE(ASSEMBLER_WX_EXCLUSIVE)
static void makeWritable(void* start, size_t size)
@@ -232,7 +240,13 @@ private:
#if ENABLE(ASSEMBLER_WX_EXCLUSIVE)
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;
+ DemandExecutableAllocator* allocator() { return m_allocator.get(); }
#endif
+#endif
+
};
#endif // ENABLE(JIT) && ENABLE(ASSEMBLER)
diff --git a/Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp b/Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp
index 37a57e8b7..959ea744b 100644
--- a/Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp
+++ b/Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp
@@ -104,6 +104,10 @@ ExecutableAllocator::ExecutableAllocator(JSGlobalData&)
ASSERT(allocator);
}
+ExecutableAllocator::~ExecutableAllocator()
+{
+}
+
bool ExecutableAllocator::isValid() const
{
return !!allocator->bytesReserved();
@@ -115,10 +119,23 @@ bool ExecutableAllocator::underMemoryPressure()
return statistics.bytesAllocated > statistics.bytesReserved / 2;
}
-PassRefPtr<ExecutableMemoryHandle> ExecutableAllocator::allocate(JSGlobalData& globalData, size_t sizeInBytes, void* ownerUID)
+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;
+ return static_cast<double>(statistics.bytesReserved) /
+ (statistics.bytesReserved - bytesAllocated);
+}
+
+PassRefPtr<ExecutableMemoryHandle> ExecutableAllocator::allocate(JSGlobalData& globalData, size_t sizeInBytes, void* ownerUID, JITCompilationEffort effort)
{
RefPtr<ExecutableMemoryHandle> result = allocator->allocate(sizeInBytes, ownerUID);
if (!result) {
+ if (effort == JITCompilationCanFail)
+ return result;
releaseExecutableMemory(globalData);
result = allocator->allocate(sizeInBytes, ownerUID);
if (!result)
diff --git a/Source/JavaScriptCore/jit/HostCallReturnValue.cpp b/Source/JavaScriptCore/jit/HostCallReturnValue.cpp
index 924bc7671..9d449c374 100644
--- a/Source/JavaScriptCore/jit/HostCallReturnValue.cpp
+++ b/Source/JavaScriptCore/jit/HostCallReturnValue.cpp
@@ -27,7 +27,7 @@
#include "HostCallReturnValue.h"
#include "CallFrame.h"
-#include "InlineASM.h"
+#include <wtf/InlineASM.h>
#include "JSObject.h"
#include "JSValueInlineMethods.h"
#include "ScopeChain.h"
diff --git a/Source/JavaScriptCore/jit/JIT.cpp b/Source/JavaScriptCore/jit/JIT.cpp
index 2adc596ce..541cc896a 100644
--- a/Source/JavaScriptCore/jit/JIT.cpp
+++ b/Source/JavaScriptCore/jit/JIT.cpp
@@ -35,7 +35,7 @@ JSC::MacroAssemblerX86Common::SSE2CheckState JSC::MacroAssemblerX86Common::s_sse
#endif
#include "CodeBlock.h"
-#include "CryptographicallyRandomNumber.h"
+#include <wtf/CryptographicallyRandomNumber.h>
#include "DFGNode.h" // for DFG_SUCCESS_STATS
#include "Interpreter.h"
#include "JITInlineMethods.h"
@@ -102,7 +102,7 @@ void JIT::emitOptimizationCheck(OptimizationCheckKind kind)
Jump skipOptimize = branchAdd32(Signed, TrustedImm32(kind == LoopOptimizationCheck ? Options::executionCounterIncrementForLoop : Options::executionCounterIncrementForReturn), AbsoluteAddress(m_codeBlock->addressOfJITExecuteCounter()));
JITStubCall stubCall(this, kind == LoopOptimizationCheck ? cti_optimize_from_loop : cti_optimize_from_ret);
if (kind == LoopOptimizationCheck)
- stubCall.addArgument(Imm32(m_bytecodeOffset));
+ stubCall.addArgument(TrustedImm32(m_bytecodeOffset));
stubCall.call();
skipOptimize.link(this);
}
@@ -235,14 +235,10 @@ void JIT::privateCompileMainPass()
DEFINE_UNARY_OP(op_is_object)
DEFINE_UNARY_OP(op_is_string)
DEFINE_UNARY_OP(op_is_undefined)
-#if USE(JSVALUE64)
- DEFINE_UNARY_OP(op_negate)
-#endif
DEFINE_UNARY_OP(op_typeof)
DEFINE_OP(op_add)
DEFINE_OP(op_bitand)
- DEFINE_OP(op_bitnot)
DEFINE_OP(op_bitor)
DEFINE_OP(op_bitxor)
DEFINE_OP(op_call)
@@ -302,9 +298,7 @@ void JIT::privateCompileMainPass()
DEFINE_OP(op_mod)
DEFINE_OP(op_mov)
DEFINE_OP(op_mul)
-#if USE(JSVALUE32_64)
DEFINE_OP(op_negate)
-#endif
DEFINE_OP(op_neq)
DEFINE_OP(op_neq_null)
DEFINE_OP(op_new_array)
@@ -437,7 +431,6 @@ void JIT::privateCompileSlowCases()
switch (m_interpreter->getOpcodeID(currentInstruction->u.opcode)) {
DEFINE_SLOWCASE_OP(op_add)
DEFINE_SLOWCASE_OP(op_bitand)
- DEFINE_SLOWCASE_OP(op_bitnot)
DEFINE_SLOWCASE_OP(op_bitor)
DEFINE_SLOWCASE_OP(op_bitxor)
DEFINE_SLOWCASE_OP(op_call)
@@ -475,10 +468,9 @@ void JIT::privateCompileSlowCases()
DEFINE_SLOWCASE_OP(op_method_check)
DEFINE_SLOWCASE_OP(op_mod)
DEFINE_SLOWCASE_OP(op_mul)
-#if USE(JSVALUE32_64)
DEFINE_SLOWCASE_OP(op_negate)
-#endif
DEFINE_SLOWCASE_OP(op_neq)
+ DEFINE_SLOWCASE_OP(op_new_array)
DEFINE_SLOWCASE_OP(op_new_object)
DEFINE_SLOWCASE_OP(op_new_func)
DEFINE_SLOWCASE_OP(op_new_func_exp)
@@ -509,7 +501,7 @@ void JIT::privateCompileSlowCases()
#if ENABLE(VALUE_PROFILER)
if (m_canBeOptimized)
- add32(Imm32(1), AbsoluteAddress(&rareCaseProfile->m_counter));
+ add32(TrustedImm32(1), AbsoluteAddress(&rareCaseProfile->m_counter));
#endif
emitJumpSlowToHot(jump(), 0);
@@ -527,7 +519,7 @@ void JIT::privateCompileSlowCases()
#endif
}
-JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck)
+JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck, JITCompilationEffort effort)
{
#if ENABLE(JIT_VERBOSE_OSR)
printf("Compiling JIT code!\n");
@@ -581,7 +573,7 @@ JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck)
}
#endif
- addPtr(Imm32(m_codeBlock->m_numCalleeRegisters * sizeof(Register)), callFrameRegister, regT1);
+ addPtr(TrustedImm32(m_codeBlock->m_numCalleeRegisters * sizeof(Register)), callFrameRegister, regT1);
registerFileCheck = branchPtr(Below, AbsoluteAddress(m_globalData->interpreter->registerFile().addressOfEnd()), regT1);
}
@@ -589,7 +581,7 @@ JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck)
#if ENABLE(VALUE_PROFILER)
if (m_canBeOptimized)
- add32(Imm32(1), AbsoluteAddress(&m_codeBlock->m_executionEntryCount));
+ add32(TrustedImm32(1), AbsoluteAddress(&m_codeBlock->m_executionEntryCount));
#endif
privateCompileMainPass();
@@ -625,7 +617,9 @@ JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck)
ASSERT(m_jmpTable.isEmpty());
- LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock);
+ LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock, effort);
+ if (patchBuffer.didFailToAllocate())
+ return JITCode();
// Translate vPC offsets into addresses in JIT generated code, for switch tables.
for (unsigned i = 0; i < m_switches.size(); ++i) {
@@ -702,7 +696,7 @@ JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck)
}
#if ENABLE(DFG_JIT) || ENABLE(LLINT)
- if (m_canBeOptimized
+ if (canBeOptimized()
#if ENABLE(LLINT)
|| true
#endif
@@ -721,6 +715,10 @@ JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck)
CodeRef result = patchBuffer.finalizeCode();
+ m_globalData->machineCodeBytesPerBytecodeWordForBaselineJIT.add(
+ static_cast<double>(result.size()) /
+ static_cast<double>(m_codeBlock->instructions().size()));
+
#if ENABLE(JIT_VERBOSE)
dataLog("JIT generated code for %p at [%p, %p).\n", m_codeBlock, result.executableMemory()->start(), result.executableMemory()->end());
#endif
diff --git a/Source/JavaScriptCore/jit/JIT.h b/Source/JavaScriptCore/jit/JIT.h
index a2bc4272a..2d2841baf 100644
--- a/Source/JavaScriptCore/jit/JIT.h
+++ b/Source/JavaScriptCore/jit/JIT.h
@@ -199,9 +199,9 @@ namespace JSC {
static const int patchPutByIdDefaultOffset = 256;
public:
- static JITCode compile(JSGlobalData* globalData, CodeBlock* codeBlock, CodePtr* functionEntryArityCheck = 0)
+ static JITCode compile(JSGlobalData* globalData, CodeBlock* codeBlock, JITCompilationEffort effort, CodePtr* functionEntryArityCheck = 0)
{
- return JIT(globalData, codeBlock).privateCompile(functionEntryArityCheck);
+ return JIT(globalData, codeBlock).privateCompile(functionEntryArityCheck, effort);
}
static void compileGetByIdProto(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset, ReturnAddressPtr returnAddress)
@@ -254,8 +254,13 @@ namespace JSC {
static CodeRef compileCTINativeCall(JSGlobalData* globalData, NativeFunction func)
{
- if (!globalData->canUseJIT())
+ if (!globalData->canUseJIT()) {
+#if ENABLE(LLINT)
+ return CodeRef::createLLIntCodeRef(llint_native_call_trampoline);
+#else
return CodeRef();
+#endif
+ }
JIT jit(globalData, 0);
return jit.privateCompileCTINativeCall(globalData, func);
}
@@ -291,7 +296,7 @@ namespace JSC {
void privateCompileMainPass();
void privateCompileLinkPass();
void privateCompileSlowCases();
- JITCode privateCompile(CodePtr* functionEntryArityCheck);
+ JITCode privateCompile(CodePtr* functionEntryArityCheck, JITCompilationEffort);
void privateCompileGetByIdProto(StructureStubInfo*, Structure*, Structure* prototypeStructure, const Identifier&, const PropertySlot&, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame);
void privateCompileGetByIdSelfList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, const Identifier&, const PropertySlot&, size_t cachedOffset);
void privateCompileGetByIdProtoList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, Structure* prototypeStructure, const Identifier&, const PropertySlot&, size_t cachedOffset, CallFrame* callFrame);
@@ -336,8 +341,10 @@ namespace JSC {
void emitWriteBarrier(JSCell* owner, RegisterID value, RegisterID scratch, WriteBarrierMode, WriteBarrierUseKind);
template<typename ClassType, bool destructor, typename StructureType> void emitAllocateBasicJSObject(StructureType, RegisterID result, RegisterID storagePtr);
+ void emitAllocateBasicStorage(size_t, RegisterID result, RegisterID storagePtr);
template<typename T> void emitAllocateJSFinalObject(T structure, RegisterID result, RegisterID storagePtr);
void emitAllocateJSFunction(FunctionExecutable*, RegisterID scopeChain, RegisterID result, RegisterID storagePtr);
+ void emitAllocateJSArray(unsigned valuesRegister, unsigned length, RegisterID cellResult, RegisterID storageResult, RegisterID storagePtr);
#if ENABLE(VALUE_PROFILER)
// This assumes that the value to profile is in regT0 and that regT3 is available for
@@ -464,7 +471,7 @@ namespace JSC {
#if ENABLE(OPCODE_SAMPLING)
#error "OPCODE_SAMPLING is not yet supported"
#else
- static const int patchOffsetGetByIdSlowCaseCall = 48;
+ static const int patchOffsetGetByIdSlowCaseCall = 52;
#endif
static const int patchOffsetOpCallCompareToJump = 16;
@@ -500,7 +507,7 @@ namespace JSC {
#if ENABLE(OPCODE_SAMPLING)
#error "OPCODE_SAMPLING is not yet supported"
#else
- static const int patchOffsetGetByIdSlowCaseCall = 64;
+ static const int patchOffsetGetByIdSlowCaseCall = 68;
#endif
static const int patchOffsetOpCallCompareToJump = 32;
static const int patchOffsetMethodCheckProtoObj = 32;
@@ -518,7 +525,7 @@ namespace JSC {
#if ENABLE(OPCODE_SAMPLING)
#error "OPCODE_SAMPLING is not yet supported"
#else
- static const int patchOffsetGetByIdSlowCaseCall = 64;
+ static const int patchOffsetGetByIdSlowCaseCall = 68;
#endif
static const int patchOffsetOpCallCompareToJump = 32;
static const int patchOffsetMethodCheckProtoObj = 32;
@@ -778,7 +785,6 @@ namespace JSC {
void emit_op_add(Instruction*);
void emit_op_bitand(Instruction*);
- void emit_op_bitnot(Instruction*);
void emit_op_bitor(Instruction*);
void emit_op_bitxor(Instruction*);
void emit_op_call(Instruction*);
@@ -898,7 +904,6 @@ namespace JSC {
void emitSlow_op_add(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_bitand(Instruction*, Vector<SlowCaseEntry>::iterator&);
- void emitSlow_op_bitnot(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_bitor(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_bitxor(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_call(Instruction*, Vector<SlowCaseEntry>::iterator&);
@@ -957,7 +962,7 @@ namespace JSC {
void emitSlow_op_urshift(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_new_func(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_new_func_exp(Instruction*, Vector<SlowCaseEntry>::iterator&);
-
+ void emitSlow_op_new_array(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitRightShift(Instruction*, bool isUnsigned);
void emitRightShiftSlowCase(Instruction*, Vector<SlowCaseEntry>::iterator&, bool isUnsigned);
diff --git a/Source/JavaScriptCore/jit/JITArithmetic.cpp b/Source/JavaScriptCore/jit/JITArithmetic.cpp
index 362cc6241..1b32e3bcf 100644
--- a/Source/JavaScriptCore/jit/JITArithmetic.cpp
+++ b/Source/JavaScriptCore/jit/JITArithmetic.cpp
@@ -192,6 +192,42 @@ void JIT::emitSlow_op_jngreatereq(Instruction* currentInstruction, Vector<SlowCa
#if USE(JSVALUE64)
+void JIT::emit_op_negate(Instruction* currentInstruction)
+{
+ unsigned dst = currentInstruction[1].u.operand;
+ unsigned src = currentInstruction[2].u.operand;
+
+ emitGetVirtualRegister(src, regT0);
+
+ Jump srcNotInt = emitJumpIfNotImmediateInteger(regT0);
+ addSlowCase(branchTest32(Zero, regT0, TrustedImm32(0x7fffffff)));
+ neg32(regT0);
+ emitFastArithReTagImmediate(regT0, regT0);
+
+ Jump end = jump();
+
+ srcNotInt.link(this);
+ emitJumpSlowCaseIfNotImmediateNumber(regT0);
+
+ move(TrustedImmPtr(reinterpret_cast<void*>(0x8000000000000000ull)), regT1);
+ xorPtr(regT1, regT0);
+
+ end.link(this);
+ emitPutVirtualRegister(dst);
+}
+
+void JIT::emitSlow_op_negate(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ unsigned dst = currentInstruction[1].u.operand;
+
+ linkSlowCase(iter); // 0x7fffffff check
+ linkSlowCase(iter); // double check
+
+ JITStubCall stubCall(this, cti_op_negate);
+ stubCall.addArgument(regT1, regT0);
+ stubCall.call(dst);
+}
+
void JIT::emit_op_lshift(Instruction* currentInstruction)
{
unsigned result = currentInstruction[1].u.operand;
@@ -797,13 +833,13 @@ void JIT::compileBinaryArithOp(OpcodeID opcodeID, unsigned, unsigned op1, unsign
addSlowCase(branchMul32(Overflow, regT1, regT2));
JumpList done;
done.append(branchTest32(NonZero, regT2));
- Jump negativeZero = branch32(LessThan, regT0, Imm32(0));
- done.append(branch32(GreaterThanOrEqual, regT1, Imm32(0)));
+ Jump negativeZero = branch32(LessThan, regT0, TrustedImm32(0));
+ done.append(branch32(GreaterThanOrEqual, regT1, TrustedImm32(0)));
negativeZero.link(this);
// We only get here if we have a genuine negative zero. Record this,
// so that the speculative JIT knows that we failed speculation
// because of a negative zero.
- add32(Imm32(1), AbsoluteAddress(&profile->m_counter));
+ add32(TrustedImm32(1), AbsoluteAddress(&profile->m_counter));
addSlowCase(jump());
done.link(this);
move(regT2, regT0);
@@ -927,13 +963,13 @@ void JIT::emit_op_add(Instruction* currentInstruction)
if (isOperandConstantImmediateInt(op1)) {
emitGetVirtualRegister(op2, regT0);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
- addSlowCase(branchAdd32(Overflow, Imm32(getConstantOperandImmediateInt(op1)), regT0));
- emitFastArithIntToImmNoCheck(regT0, regT0);
+ addSlowCase(branchAdd32(Overflow, regT0, Imm32(getConstantOperandImmediateInt(op1)), regT1));
+ emitFastArithIntToImmNoCheck(regT1, regT0);
} else if (isOperandConstantImmediateInt(op2)) {
emitGetVirtualRegister(op1, regT0);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
- addSlowCase(branchAdd32(Overflow, Imm32(getConstantOperandImmediateInt(op2)), regT0));
- emitFastArithIntToImmNoCheck(regT0, regT0);
+ addSlowCase(branchAdd32(Overflow, regT0, Imm32(getConstantOperandImmediateInt(op2)), regT1));
+ emitFastArithIntToImmNoCheck(regT1, regT0);
} else
compileBinaryArithOp(op_add, result, op1, op2, types);
@@ -973,8 +1009,8 @@ void JIT::emit_op_mul(Instruction* currentInstruction)
#endif
emitGetVirtualRegister(op2, regT0);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
- addSlowCase(branchMul32(Overflow, Imm32(value), regT0, regT0));
- emitFastArithReTagImmediate(regT0, regT0);
+ addSlowCase(branchMul32(Overflow, Imm32(value), regT0, regT1));
+ emitFastArithReTagImmediate(regT1, regT0);
} else if (isOperandConstantImmediateInt(op2) && ((value = getConstantOperandImmediateInt(op2)) > 0)) {
#if ENABLE(VALUE_PROFILER)
// Add a special fast case profile because the DFG JIT will expect one.
@@ -982,8 +1018,8 @@ void JIT::emit_op_mul(Instruction* currentInstruction)
#endif
emitGetVirtualRegister(op1, regT0);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
- addSlowCase(branchMul32(Overflow, Imm32(value), regT0, regT0));
- emitFastArithReTagImmediate(regT0, regT0);
+ addSlowCase(branchMul32(Overflow, Imm32(value), regT0, regT1));
+ emitFastArithReTagImmediate(regT1, regT0);
} else
compileBinaryArithOp(op_mul, result, op1, op2, types);
@@ -1069,7 +1105,7 @@ void JIT::emit_op_div(Instruction* currentInstruction)
emitFastArithReTagImmediate(regT0, regT0);
Jump isInteger = jump();
notInteger.link(this);
- add32(Imm32(1), AbsoluteAddress(&m_codeBlock->addSpecialFastCaseProfile(m_bytecodeOffset)->m_counter));
+ add32(TrustedImm32(1), AbsoluteAddress(&m_codeBlock->addSpecialFastCaseProfile(m_bytecodeOffset)->m_counter));
moveDoubleToPtr(fpRegT0, regT0);
subPtr(tagTypeNumberRegister, regT0);
isInteger.link(this);
diff --git a/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp b/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp
index 4916261fe..11a758103 100644
--- a/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp
+++ b/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp
@@ -448,31 +448,6 @@ void JIT::emitSlow_op_bitxor(Instruction* currentInstruction, Vector<SlowCaseEnt
stubCall.call(dst);
}
-// BitNot (~)
-
-void JIT::emit_op_bitnot(Instruction* currentInstruction)
-{
- unsigned dst = currentInstruction[1].u.operand;
- unsigned src = currentInstruction[2].u.operand;
-
- emitLoad(src, regT1, regT0);
- addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
-
- not32(regT0);
- emitStoreAndMapInt32(dst, regT1, regT0, dst == src, OPCODE_LENGTH(op_bitnot));
-}
-
-void JIT::emitSlow_op_bitnot(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
- unsigned dst = currentInstruction[1].u.operand;
-
- linkSlowCase(iter); // int32 check
-
- JITStubCall stubCall(this, cti_op_bitnot);
- stubCall.addArgument(regT1, regT0);
- stubCall.call(dst);
-}
-
// PostInc (i++)
void JIT::emit_op_post_inc(Instruction* currentInstruction)
@@ -504,7 +479,7 @@ void JIT::emitSlow_op_post_inc(Instruction* currentInstruction, Vector<SlowCaseE
JITStubCall stubCall(this, cti_op_post_inc);
stubCall.addArgument(srcDst);
- stubCall.addArgument(Imm32(srcDst));
+ stubCall.addArgument(TrustedImm32(srcDst));
stubCall.call(dst);
}
@@ -644,9 +619,9 @@ void JIT::emit_op_add(Instruction* currentInstruction)
void JIT::emitAdd32Constant(unsigned dst, unsigned op, int32_t constant, ResultType opType)
{
// Int32 case.
- emitLoad(op, regT1, regT0);
+ emitLoad(op, regT1, regT2);
Jump notInt32 = branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag));
- addSlowCase(branchAdd32(Overflow, Imm32(constant), regT0));
+ addSlowCase(branchAdd32(Overflow, regT2, Imm32(constant), regT0));
emitStoreInt32(dst, regT0, (op == dst));
// Double case.
@@ -757,8 +732,13 @@ void JIT::emitSub32Constant(unsigned dst, unsigned op, int32_t constant, ResultT
// Int32 case.
emitLoad(op, regT1, regT0);
Jump notInt32 = branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag));
- addSlowCase(branchSub32(Overflow, Imm32(constant), regT0));
- emitStoreInt32(dst, regT0, (op == dst));
+#if ENABLE(JIT_CONSTANT_BLINDING)
+ addSlowCase(branchSub32(Overflow, regT0, Imm32(constant), regT2, regT3));
+#else
+ addSlowCase(branchSub32(Overflow, regT0, Imm32(constant), regT2));
+#endif
+
+ emitStoreInt32(dst, regT2, (op == dst));
// Double case.
if (!supportsFloatingPoint()) {
@@ -886,7 +866,7 @@ void JIT::emitBinaryDoubleOp(OpcodeID opcodeID, unsigned dst, unsigned op1, unsi
emitStoreInt32(dst, regT2);
Jump isInteger = jump();
notInteger.link(this);
- add32(Imm32(1), AbsoluteAddress(&m_codeBlock->specialFastCaseProfileForBytecodeOffset(m_bytecodeOffset)->m_counter));
+ add32(TrustedImm32(1), AbsoluteAddress(&m_codeBlock->specialFastCaseProfileForBytecodeOffset(m_bytecodeOffset)->m_counter));
emitStoreDouble(dst, fpRegT1);
isInteger.link(this);
#else
@@ -990,7 +970,7 @@ void JIT::emitBinaryDoubleOp(OpcodeID opcodeID, unsigned dst, unsigned op1, unsi
emitStoreInt32(dst, regT2);
Jump isInteger = jump();
notInteger.link(this);
- add32(Imm32(1), AbsoluteAddress(&m_codeBlock->specialFastCaseProfileForBytecodeOffset(m_bytecodeOffset)->m_counter));
+ add32(TrustedImm32(1), AbsoluteAddress(&m_codeBlock->specialFastCaseProfileForBytecodeOffset(m_bytecodeOffset)->m_counter));
emitStoreDouble(dst, fpRegT0);
isInteger.link(this);
#else
@@ -1096,7 +1076,7 @@ void JIT::emitSlow_op_mul(Instruction* currentInstruction, Vector<SlowCaseEntry>
// We only get here if we have a genuine negative zero. Record this,
// so that the speculative JIT knows that we failed speculation
// because of a negative zero.
- add32(Imm32(1), AbsoluteAddress(&m_codeBlock->specialFastCaseProfileForBytecodeOffset(m_bytecodeOffset)->m_counter));
+ add32(TrustedImm32(1), AbsoluteAddress(&m_codeBlock->specialFastCaseProfileForBytecodeOffset(m_bytecodeOffset)->m_counter));
#endif
overflow.link(this);
@@ -1175,7 +1155,7 @@ void JIT::emit_op_div(Instruction* currentInstruction)
emitStoreInt32(dst, regT2);
end.append(jump());
notInteger.link(this);
- add32(Imm32(1), AbsoluteAddress(&m_codeBlock->specialFastCaseProfileForBytecodeOffset(m_bytecodeOffset)->m_counter));
+ add32(TrustedImm32(1), AbsoluteAddress(&m_codeBlock->specialFastCaseProfileForBytecodeOffset(m_bytecodeOffset)->m_counter));
emitStoreDouble(dst, fpRegT0);
#else
emitStoreDouble(dst, fpRegT0);
diff --git a/Source/JavaScriptCore/jit/JITCall.cpp b/Source/JavaScriptCore/jit/JITCall.cpp
index 69dc9540e..73d017d05 100644
--- a/Source/JavaScriptCore/jit/JITCall.cpp
+++ b/Source/JavaScriptCore/jit/JITCall.cpp
@@ -83,8 +83,7 @@ void JIT::compileLoadVarargs(Instruction* instruction)
slowCase.append(branchPtr(Below, AbsoluteAddress(m_globalData->interpreter->registerFile().addressOfEnd()), regT1));
// Initialize ArgumentCount.
- emitFastArithReTagImmediate(regT0, regT2);
- storePtr(regT2, Address(regT1, RegisterFile::ArgumentCount * static_cast<int>(sizeof(Register))));
+ store32(regT0, Address(regT1, RegisterFile::ArgumentCount * static_cast<int>(sizeof(Register)) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
// Initialize 'this'.
emitGetVirtualRegister(thisValue, regT2);
@@ -93,13 +92,13 @@ void JIT::compileLoadVarargs(Instruction* instruction)
// Copy arguments.
neg32(regT0);
signExtend32ToPtr(regT0, regT0);
- end.append(branchAddPtr(Zero, Imm32(1), regT0));
+ end.append(branchAddPtr(Zero, TrustedImm32(1), regT0));
// regT0: -argumentCount
Label copyLoop = label();
loadPtr(BaseIndex(callFrameRegister, regT0, TimesEight, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))), regT2);
storePtr(regT2, BaseIndex(regT1, regT0, TimesEight, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))));
- branchAddPtr(NonZero, Imm32(1), regT0).linkTo(copyLoop, this);
+ branchAddPtr(NonZero, TrustedImm32(1), regT0).linkTo(copyLoop, this);
end.append(jump());
}
diff --git a/Source/JavaScriptCore/jit/JITCall32_64.cpp b/Source/JavaScriptCore/jit/JITCall32_64.cpp
index b84ad1a49..7fb6c78b9 100644
--- a/Source/JavaScriptCore/jit/JITCall32_64.cpp
+++ b/Source/JavaScriptCore/jit/JITCall32_64.cpp
@@ -171,7 +171,7 @@ void JIT::compileLoadVarargs(Instruction* instruction)
// Copy arguments.
neg32(regT2);
- end.append(branchAdd32(Zero, Imm32(1), regT2));
+ end.append(branchAdd32(Zero, TrustedImm32(1), regT2));
// regT2: -argumentCount;
Label copyLoop = label();
@@ -179,7 +179,7 @@ void JIT::compileLoadVarargs(Instruction* instruction)
load32(BaseIndex(callFrameRegister, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag) +(CallFrame::thisArgumentOffset() * 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)))));
- branchAdd32(NonZero, Imm32(1), regT2).linkTo(copyLoop, this);
+ branchAdd32(NonZero, TrustedImm32(1), regT2).linkTo(copyLoop, this);
end.append(jump());
}
diff --git a/Source/JavaScriptCore/jit/JITCompilationEffort.h b/Source/JavaScriptCore/jit/JITCompilationEffort.h
new file mode 100644
index 000000000..5eb680178
--- /dev/null
+++ b/Source/JavaScriptCore/jit/JITCompilationEffort.h
@@ -0,0 +1,39 @@
+/*
+ * 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 JITCompilationEffort_h
+#define JITCompilationEffort_h
+
+namespace JSC {
+
+enum JITCompilationEffort {
+ JITCompilationCanFail,
+ JITCompilationMustSucceed
+};
+
+} // namespace JSC
+
+#endif // JITCompilationEffort_h
+
diff --git a/Source/JavaScriptCore/jit/JITDriver.h b/Source/JavaScriptCore/jit/JITDriver.h
index b204c7737..66cf51925 100644
--- a/Source/JavaScriptCore/jit/JITDriver.h
+++ b/Source/JavaScriptCore/jit/JITDriver.h
@@ -38,7 +38,7 @@
namespace JSC {
template<typename CodeBlockType>
-inline bool jitCompileIfAppropriate(JSGlobalData& globalData, OwnPtr<CodeBlockType>& codeBlock, JITCode& jitCode, JITCode::JITType jitType)
+inline bool jitCompileIfAppropriate(JSGlobalData& globalData, OwnPtr<CodeBlockType>& codeBlock, JITCode& jitCode, JITCode::JITType jitType, JITCompilationEffort effort)
{
if (jitType == codeBlock->getJITType())
return true;
@@ -48,6 +48,8 @@ inline bool jitCompileIfAppropriate(JSGlobalData& globalData, OwnPtr<CodeBlockTy
codeBlock->unlinkIncomingCalls();
+ JITCode oldJITCode = jitCode;
+
bool dfgCompiled = false;
if (jitType == JITCode::DFGJIT)
dfgCompiled = DFG::tryCompile(globalData, codeBlock.get(), jitCode);
@@ -57,16 +59,21 @@ inline bool jitCompileIfAppropriate(JSGlobalData& globalData, OwnPtr<CodeBlockTy
} else {
if (codeBlock->alternative()) {
codeBlock = static_pointer_cast<CodeBlockType>(codeBlock->releaseAlternative());
+ jitCode = oldJITCode;
+ return false;
+ }
+ jitCode = JIT::compile(&globalData, codeBlock.get(), effort);
+ if (!jitCode) {
+ jitCode = oldJITCode;
return false;
}
- jitCode = JIT::compile(&globalData, codeBlock.get());
}
codeBlock->setJITCode(jitCode, MacroAssemblerCodePtr());
return true;
}
-inline bool jitCompileFunctionIfAppropriate(JSGlobalData& globalData, OwnPtr<FunctionCodeBlock>& codeBlock, JITCode& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck, SharedSymbolTable*& symbolTable, JITCode::JITType jitType)
+inline bool jitCompileFunctionIfAppropriate(JSGlobalData& globalData, OwnPtr<FunctionCodeBlock>& codeBlock, JITCode& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck, SharedSymbolTable*& symbolTable, JITCode::JITType jitType, JITCompilationEffort effort)
{
if (jitType == codeBlock->getJITType())
return true;
@@ -76,6 +83,9 @@ inline bool jitCompileFunctionIfAppropriate(JSGlobalData& globalData, OwnPtr<Fun
codeBlock->unlinkIncomingCalls();
+ JITCode oldJITCode = jitCode;
+ MacroAssemblerCodePtr oldJITCodeWithArityCheck = jitCodeWithArityCheck;
+
bool dfgCompiled = false;
if (jitType == JITCode::DFGJIT)
dfgCompiled = DFG::tryCompileFunction(globalData, codeBlock.get(), jitCode, jitCodeWithArityCheck);
@@ -86,9 +96,16 @@ inline bool jitCompileFunctionIfAppropriate(JSGlobalData& globalData, OwnPtr<Fun
if (codeBlock->alternative()) {
codeBlock = static_pointer_cast<FunctionCodeBlock>(codeBlock->releaseAlternative());
symbolTable = codeBlock->sharedSymbolTable();
+ jitCode = oldJITCode;
+ jitCodeWithArityCheck = oldJITCodeWithArityCheck;
+ return false;
+ }
+ jitCode = JIT::compile(&globalData, codeBlock.get(), effort, &jitCodeWithArityCheck);
+ if (!jitCode) {
+ jitCode = oldJITCode;
+ jitCodeWithArityCheck = oldJITCodeWithArityCheck;
return false;
}
- jitCode = JIT::compile(&globalData, codeBlock.get(), &jitCodeWithArityCheck);
}
codeBlock->setJITCode(jitCode, jitCodeWithArityCheck);
diff --git a/Source/JavaScriptCore/jit/JITExceptions.cpp b/Source/JavaScriptCore/jit/JITExceptions.cpp
index 2edd3408f..ab1180716 100644
--- a/Source/JavaScriptCore/jit/JITExceptions.cpp
+++ b/Source/JavaScriptCore/jit/JITExceptions.cpp
@@ -48,8 +48,7 @@ ExceptionHandler genericThrow(JSGlobalData* globalData, ExecState* callFrame, JS
Instruction* catchPCForInterpreter = 0;
if (handler) {
catchRoutine = handler->nativeCode.executableAddress();
- if (callFrame->codeBlock()->hasInstructions())
- catchPCForInterpreter = &callFrame->codeBlock()->instructions()[handler->target];
+ catchPCForInterpreter = &callFrame->codeBlock()->instructions()[handler->target];
} else
catchRoutine = FunctionPtr(ctiOpThrowNotCaught).value();
diff --git a/Source/JavaScriptCore/jit/JITInlineMethods.h b/Source/JavaScriptCore/jit/JITInlineMethods.h
index e0310569d..998d5ac18 100644
--- a/Source/JavaScriptCore/jit/JITInlineMethods.h
+++ b/Source/JavaScriptCore/jit/JITInlineMethods.h
@@ -269,7 +269,7 @@ ALWAYS_INLINE void JIT::updateTopCallFrame()
#if USE(JSVALUE32_64)
storePtr(TrustedImmPtr(m_codeBlock->instructions().begin() + m_bytecodeOffset + 1), intTagFor(RegisterFile::ArgumentCount));
#else
- store32(Imm32(m_bytecodeOffset + 1), intTagFor(RegisterFile::ArgumentCount));
+ store32(TrustedImm32(m_bytecodeOffset + 1), intTagFor(RegisterFile::ArgumentCount));
#endif
}
storePtr(callFrameRegister, &m_globalData->topCallFrame);
@@ -459,6 +459,78 @@ inline void JIT::emitAllocateJSFunction(FunctionExecutable* executable, Register
#endif
}
+inline void JIT::emitAllocateBasicStorage(size_t size, RegisterID result, RegisterID storagePtr)
+{
+ CopiedAllocator* allocator = &m_globalData->heap.storageAllocator();
+
+ // FIXME: We need to check for wrap-around.
+ // Check to make sure that the allocation will fit in the current block.
+ loadPtr(&allocator->m_currentOffset, result);
+ addPtr(TrustedImm32(size), result);
+ loadPtr(&allocator->m_currentBlock, storagePtr);
+ addPtr(TrustedImm32(HeapBlock::s_blockSize), storagePtr);
+ addSlowCase(branchPtr(AboveOrEqual, result, storagePtr));
+
+ // Load the original offset.
+ loadPtr(&allocator->m_currentOffset, result);
+
+ // Bump the pointer forward.
+ move(result, storagePtr);
+ addPtr(TrustedImm32(size), storagePtr);
+ storePtr(storagePtr, &allocator->m_currentOffset);
+}
+
+inline void JIT::emitAllocateJSArray(unsigned valuesRegister, unsigned length, RegisterID cellResult, RegisterID storageResult, RegisterID storagePtr)
+{
+ unsigned initialLength = std::max(length, 4U);
+ size_t initialStorage = JSArray::storageSize(initialLength);
+
+ // Allocate the cell for the array.
+ emitAllocateBasicJSObject<JSArray, false>(TrustedImmPtr(m_codeBlock->globalObject()->arrayStructure()), cellResult, storagePtr);
+
+ // Allocate the backing store for the array.
+ emitAllocateBasicStorage(initialStorage, storageResult, storagePtr);
+
+ // Store all the necessary info in the ArrayStorage.
+ storePtr(storageResult, Address(storageResult, ArrayStorage::allocBaseOffset()));
+ store32(Imm32(length), Address(storageResult, ArrayStorage::lengthOffset()));
+ store32(Imm32(length), Address(storageResult, ArrayStorage::numValuesInVectorOffset()));
+
+ // Store the newly allocated ArrayStorage.
+ storePtr(storageResult, Address(cellResult, JSArray::storageOffset()));
+
+ // Store the vector length and index bias.
+ store32(Imm32(initialLength), Address(cellResult, JSArray::vectorLengthOffset()));
+ store32(TrustedImm32(0), Address(cellResult, JSArray::indexBiasOffset()));
+
+ // Initialize the subclass data and the sparse value map.
+ storePtr(TrustedImmPtr(0), Address(cellResult, JSArray::subclassDataOffset()));
+ storePtr(TrustedImmPtr(0), Address(cellResult, JSArray::sparseValueMapOffset()));
+
+ // Store the values we have.
+ for (unsigned i = 0; i < length; i++) {
+#if USE(JSVALUE64)
+ loadPtr(Address(callFrameRegister, (valuesRegister + i) * sizeof(Register)), storagePtr);
+ storePtr(storagePtr, Address(storageResult, ArrayStorage::vectorOffset() + sizeof(WriteBarrier<Unknown>) * i));
+#else
+ load32(Address(callFrameRegister, (valuesRegister + i) * sizeof(Register)), storagePtr);
+ store32(storagePtr, Address(storageResult, ArrayStorage::vectorOffset() + sizeof(WriteBarrier<Unknown>) * i));
+ load32(Address(callFrameRegister, (valuesRegister + i) * sizeof(Register) + sizeof(uint32_t)), storagePtr);
+ store32(storagePtr, Address(storageResult, ArrayStorage::vectorOffset() + sizeof(WriteBarrier<Unknown>) * i + sizeof(uint32_t)));
+#endif
+ }
+
+ // Zero out the remaining slots.
+ for (unsigned i = length; i < initialLength; i++) {
+#if USE(JSVALUE64)
+ storePtr(TrustedImmPtr(0), Address(storageResult, ArrayStorage::vectorOffset() + sizeof(WriteBarrier<Unknown>) * i));
+#else
+ store32(TrustedImm32(static_cast<int>(JSValue::EmptyValueTag)), Address(storageResult, ArrayStorage::vectorOffset() + sizeof(WriteBarrier<Unknown>) * i + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
+ store32(TrustedImm32(0), Address(storageResult, ArrayStorage::vectorOffset() + sizeof(WriteBarrier<Unknown>) * i + OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
+#endif
+ }
+}
+
#if ENABLE(VALUE_PROFILER)
inline void JIT::emitValueProfilingSite(ValueProfile* valueProfile)
{
@@ -485,11 +557,11 @@ inline void JIT::emitValueProfilingSite(ValueProfile* valueProfile)
}
if (m_randomGenerator.getUint32() & 1)
- add32(Imm32(1), bucketCounterRegister);
+ add32(TrustedImm32(1), bucketCounterRegister);
else
- add32(Imm32(3), bucketCounterRegister);
- and32(Imm32(ValueProfile::bucketIndexMask), bucketCounterRegister);
- move(ImmPtr(valueProfile->m_buckets), scratch);
+ add32(TrustedImm32(3), bucketCounterRegister);
+ and32(TrustedImm32(ValueProfile::bucketIndexMask), bucketCounterRegister);
+ move(TrustedImmPtr(valueProfile->m_buckets), scratch);
#if USE(JSVALUE64)
storePtr(value, BaseIndex(scratch, bucketCounterRegister, TimesEight));
#elif USE(JSVALUE32_64)
@@ -796,7 +868,10 @@ ALWAYS_INLINE void JIT::emitGetVirtualRegister(int src, RegisterID dst)
// TODO: we want to reuse values that are already in registers if we can - add a register allocator!
if (m_codeBlock->isConstantRegisterIndex(src)) {
JSValue value = m_codeBlock->getConstant(src);
- move(ImmPtr(JSValue::encode(value)), dst);
+ if (!value.isNumber())
+ move(TrustedImmPtr(JSValue::encode(value)), dst);
+ else
+ move(ImmPtr(JSValue::encode(value)), dst);
killLastResultRegister();
return;
}
diff --git a/Source/JavaScriptCore/jit/JITOpcodes.cpp b/Source/JavaScriptCore/jit/JITOpcodes.cpp
index bc53d2cd8..2db82bf4a 100644
--- a/Source/JavaScriptCore/jit/JITOpcodes.cpp
+++ b/Source/JavaScriptCore/jit/JITOpcodes.cpp
@@ -29,6 +29,7 @@
#include "JIT.h"
#include "Arguments.h"
+#include "CopiedSpaceInlineMethods.h"
#include "Heap.h"
#include "JITInlineMethods.h"
#include "JITStubCall.h"
@@ -357,7 +358,10 @@ void JIT::emit_op_mov(Instruction* currentInstruction)
emitPutVirtualRegister(dst);
} else {
if (m_codeBlock->isConstantRegisterIndex(src)) {
- storePtr(ImmPtr(JSValue::encode(getConstantOperand(src))), Address(callFrameRegister, dst * sizeof(Register)));
+ if (!getConstantOperand(src).isNumber())
+ storePtr(TrustedImmPtr(JSValue::encode(getConstantOperand(src))), Address(callFrameRegister, dst * sizeof(Register)));
+ else
+ storePtr(ImmPtr(JSValue::encode(getConstantOperand(src))), Address(callFrameRegister, dst * sizeof(Register)));
if (dst == m_lastResultBytecodeRegister)
killLastResultRegister();
} else if ((src == m_lastResultBytecodeRegister) || (dst == m_lastResultBytecodeRegister)) {
@@ -389,7 +393,7 @@ void JIT::emit_op_jmp(Instruction* currentInstruction)
void JIT::emit_op_new_object(Instruction* currentInstruction)
{
- emitAllocateJSFinalObject(ImmPtr(m_codeBlock->globalObject()->emptyObjectStructure()), regT0, regT1);
+ emitAllocateJSFinalObject(TrustedImmPtr(m_codeBlock->globalObject()->emptyObjectStructure()), regT0, regT1);
emitPutVirtualRegister(currentInstruction[1].u.operand);
}
@@ -594,8 +598,8 @@ void JIT::emit_op_to_primitive(Instruction* currentInstruction)
void JIT::emit_op_strcat(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_strcat);
- stubCall.addArgument(Imm32(currentInstruction[2].u.operand));
- stubCall.addArgument(Imm32(currentInstruction[3].u.operand));
+ stubCall.addArgument(TrustedImm32(currentInstruction[2].u.operand));
+ stubCall.addArgument(TrustedImm32(currentInstruction[3].u.operand));
stubCall.call(currentInstruction[1].u.operand);
}
@@ -609,7 +613,7 @@ void JIT::emit_op_resolve_base(Instruction* currentInstruction)
void JIT::emit_op_ensure_property_exists(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_ensure_property_exists);
- stubCall.addArgument(Imm32(currentInstruction[1].u.operand));
+ stubCall.addArgument(TrustedImm32(currentInstruction[1].u.operand));
stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
stubCall.call(currentInstruction[1].u.operand);
}
@@ -618,7 +622,7 @@ void JIT::emit_op_resolve_skip(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_resolve_skip);
stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
- stubCall.addArgument(Imm32(currentInstruction[3].u.operand));
+ stubCall.addArgument(TrustedImm32(currentInstruction[3].u.operand));
stubCall.callWithValueProfiling(currentInstruction[1].u.operand);
}
@@ -654,7 +658,7 @@ void JIT::emitSlow_op_resolve_global(Instruction* currentInstruction, Vector<Slo
linkSlowCase(iter);
JITStubCall stubCall(this, cti_op_resolve_global);
stubCall.addArgument(TrustedImmPtr(ident));
- stubCall.addArgument(Imm32(currentIndex));
+ stubCall.addArgument(TrustedImm32(currentIndex));
stubCall.addArgument(regT0);
stubCall.callWithValueProfiling(dst);
}
@@ -763,20 +767,11 @@ void JIT::emit_op_eq(Instruction* currentInstruction)
emitPutVirtualRegister(currentInstruction[1].u.operand);
}
-void JIT::emit_op_bitnot(Instruction* currentInstruction)
-{
- emitGetVirtualRegister(currentInstruction[2].u.operand, regT0);
- emitJumpSlowCaseIfNotImmediateInteger(regT0);
- not32(regT0);
- emitFastArithIntToImmNoCheck(regT0, regT0);
- emitPutVirtualRegister(currentInstruction[1].u.operand);
-}
-
void JIT::emit_op_resolve_with_base(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_resolve_with_base);
stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[3].u.operand)));
- stubCall.addArgument(Imm32(currentInstruction[1].u.operand));
+ stubCall.addArgument(TrustedImm32(currentInstruction[1].u.operand));
stubCall.callWithValueProfiling(currentInstruction[2].u.operand);
}
@@ -784,7 +779,7 @@ void JIT::emit_op_resolve_with_this(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_resolve_with_this);
stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[3].u.operand)));
- stubCall.addArgument(Imm32(currentInstruction[1].u.operand));
+ stubCall.addArgument(TrustedImm32(currentInstruction[1].u.operand));
stubCall.callWithValueProfiling(currentInstruction[2].u.operand);
}
@@ -971,17 +966,25 @@ void JIT::compileOpStrictEq(Instruction* currentInstruction, CompileOpStrictEqTy
unsigned src2 = currentInstruction[3].u.operand;
emitGetVirtualRegisters(src1, regT0, src2, regT1);
-
- // Jump to a slow case if either operand is a number, or if both are JSCell*s.
+
+ // Jump slow if both are cells (to cover strings).
move(regT0, regT2);
orPtr(regT1, regT2);
addSlowCase(emitJumpIfJSCell(regT2));
- addSlowCase(emitJumpIfImmediateNumber(regT2));
+
+ // Jump slow if either is a double. First test if it's an integer, which is fine, and then test
+ // if it's a double.
+ Jump leftOK = emitJumpIfImmediateInteger(regT0);
+ addSlowCase(emitJumpIfImmediateNumber(regT0));
+ leftOK.link(this);
+ Jump rightOK = emitJumpIfImmediateInteger(regT1);
+ addSlowCase(emitJumpIfImmediateNumber(regT1));
+ rightOK.link(this);
if (type == OpStrictEq)
- compare32(Equal, regT1, regT0, regT0);
+ comparePtr(Equal, regT1, regT0, regT0);
else
- compare32(NotEqual, regT1, regT0, regT0);
+ comparePtr(NotEqual, regT1, regT0, regT0);
emitTagAsBoolImmediate(regT0);
emitPutVirtualRegister(dst);
@@ -1034,7 +1037,7 @@ void JIT::emit_op_catch(Instruction* currentInstruction)
void JIT::emit_op_jmp_scopes(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_jmp_scopes);
- stubCall.addArgument(Imm32(currentInstruction[1].u.operand));
+ stubCall.addArgument(TrustedImm32(currentInstruction[1].u.operand));
stubCall.call();
addJump(jump(), currentInstruction[2].u.operand);
}
@@ -1052,7 +1055,7 @@ void JIT::emit_op_switch_imm(Instruction* currentInstruction)
JITStubCall stubCall(this, cti_op_switch_imm);
stubCall.addArgument(scrutinee, regT2);
- stubCall.addArgument(Imm32(tableIndex));
+ stubCall.addArgument(TrustedImm32(tableIndex));
stubCall.call();
jump(regT0);
}
@@ -1070,7 +1073,7 @@ void JIT::emit_op_switch_char(Instruction* currentInstruction)
JITStubCall stubCall(this, cti_op_switch_char);
stubCall.addArgument(scrutinee, regT2);
- stubCall.addArgument(Imm32(tableIndex));
+ stubCall.addArgument(TrustedImm32(tableIndex));
stubCall.call();
jump(regT0);
}
@@ -1087,7 +1090,7 @@ void JIT::emit_op_switch_string(Instruction* currentInstruction)
JITStubCall stubCall(this, cti_op_switch_string);
stubCall.addArgument(scrutinee, regT2);
- stubCall.addArgument(Imm32(tableIndex));
+ stubCall.addArgument(TrustedImm32(tableIndex));
stubCall.call();
jump(regT0);
}
@@ -1095,7 +1098,10 @@ void JIT::emit_op_switch_string(Instruction* currentInstruction)
void JIT::emit_op_throw_reference_error(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_throw_reference_error);
- stubCall.addArgument(ImmPtr(JSValue::encode(m_codeBlock->getConstant(currentInstruction[1].u.operand))));
+ if (!m_codeBlock->getConstant(currentInstruction[1].u.operand).isNumber())
+ stubCall.addArgument(TrustedImmPtr(JSValue::encode(m_codeBlock->getConstant(currentInstruction[1].u.operand))));
+ else
+ stubCall.addArgument(ImmPtr(JSValue::encode(m_codeBlock->getConstant(currentInstruction[1].u.operand))));
stubCall.call();
}
@@ -1106,9 +1112,9 @@ void JIT::emit_op_debug(Instruction* currentInstruction)
breakpoint();
#else
JITStubCall stubCall(this, cti_op_debug);
- stubCall.addArgument(Imm32(currentInstruction[1].u.operand));
- stubCall.addArgument(Imm32(currentInstruction[2].u.operand));
- stubCall.addArgument(Imm32(currentInstruction[3].u.operand));
+ stubCall.addArgument(TrustedImm32(currentInstruction[1].u.operand));
+ stubCall.addArgument(TrustedImm32(currentInstruction[2].u.operand));
+ stubCall.addArgument(TrustedImm32(currentInstruction[3].u.operand));
stubCall.call();
#endif
}
@@ -1318,14 +1324,6 @@ void JIT::emitSlow_op_jfalse(Instruction* currentInstruction, Vector<SlowCaseEnt
emitJumpSlowToHot(branchTest32(Zero, regT0), currentInstruction[2].u.operand); // inverted!
}
-void JIT::emitSlow_op_bitnot(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
- linkSlowCase(iter);
- JITStubCall stubCall(this, cti_op_bitnot);
- stubCall.addArgument(regT0);
- stubCall.call(currentInstruction[1].u.operand);
-}
-
void JIT::emitSlow_op_jtrue(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
linkSlowCase(iter);
@@ -1380,6 +1378,7 @@ void JIT::emitSlow_op_stricteq(Instruction* currentInstruction, Vector<SlowCaseE
{
linkSlowCase(iter);
linkSlowCase(iter);
+ linkSlowCase(iter);
JITStubCall stubCall(this, cti_op_stricteq);
stubCall.addArgument(regT0);
stubCall.addArgument(regT1);
@@ -1390,6 +1389,7 @@ void JIT::emitSlow_op_nstricteq(Instruction* currentInstruction, Vector<SlowCase
{
linkSlowCase(iter);
linkSlowCase(iter);
+ linkSlowCase(iter);
JITStubCall stubCall(this, cti_op_nstricteq);
stubCall.addArgument(regT0);
stubCall.addArgument(regT1);
@@ -1565,7 +1565,7 @@ void JIT::emitSlow_op_resolve_global_dynamic(Instruction* currentInstruction, Ve
linkSlowCase(iter); // We managed to skip all the nodes in the scope chain, but the cache missed.
JITStubCall stubCall(this, cti_op_resolve_global);
stubCall.addArgument(TrustedImmPtr(ident));
- stubCall.addArgument(Imm32(currentIndex));
+ stubCall.addArgument(TrustedImm32(currentIndex));
stubCall.addArgument(regT0);
stubCall.callWithValueProfiling(dst);
}
@@ -1645,17 +1645,39 @@ void JIT::emitSlow_op_new_func_exp(Instruction* currentInstruction, Vector<SlowC
void JIT::emit_op_new_array(Instruction* currentInstruction)
{
+ int length = currentInstruction[3].u.operand;
+ if (CopiedSpace::isOversize(JSArray::storageSize(length))) {
+ JITStubCall stubCall(this, cti_op_new_array);
+ stubCall.addArgument(TrustedImm32(currentInstruction[2].u.operand));
+ stubCall.addArgument(TrustedImm32(currentInstruction[3].u.operand));
+ stubCall.call(currentInstruction[1].u.operand);
+ return;
+ }
+ int dst = currentInstruction[1].u.operand;
+ int values = currentInstruction[2].u.operand;
+
+ emitAllocateJSArray(values, length, regT0, regT1, regT2);
+ emitStoreCell(dst, regT0);
+}
+
+void JIT::emitSlow_op_new_array(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ int length = currentInstruction[3].u.operand;
+ if (CopiedSpace::isOversize(JSArray::storageSize(length)))
+ return;
+ linkSlowCase(iter); // Not enough space in MarkedSpace for cell.
+ linkSlowCase(iter); // Not enough space in CopiedSpace for storage.
JITStubCall stubCall(this, cti_op_new_array);
- stubCall.addArgument(Imm32(currentInstruction[2].u.operand));
- stubCall.addArgument(Imm32(currentInstruction[3].u.operand));
+ stubCall.addArgument(TrustedImm32(currentInstruction[2].u.operand));
+ stubCall.addArgument(TrustedImm32(currentInstruction[3].u.operand));
stubCall.call(currentInstruction[1].u.operand);
}
void JIT::emit_op_new_array_buffer(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_new_array_buffer);
- stubCall.addArgument(Imm32(currentInstruction[2].u.operand));
- stubCall.addArgument(Imm32(currentInstruction[3].u.operand));
+ stubCall.addArgument(TrustedImm32(currentInstruction[2].u.operand));
+ stubCall.addArgument(TrustedImm32(currentInstruction[3].u.operand));
stubCall.call(currentInstruction[1].u.operand);
}
diff --git a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
index 1a09302cf..b67696f35 100644
--- a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
+++ b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
@@ -536,7 +536,7 @@ void JIT::emit_op_jmp(Instruction* currentInstruction)
void JIT::emit_op_new_object(Instruction* currentInstruction)
{
- emitAllocateJSFinalObject(ImmPtr(m_codeBlock->globalObject()->emptyObjectStructure()), regT0, regT1);
+ emitAllocateJSFinalObject(TrustedImmPtr(m_codeBlock->globalObject()->emptyObjectStructure()), regT0, regT1);
emitStoreCell(currentInstruction[1].u.operand, regT0);
}
@@ -701,8 +701,8 @@ void JIT::emitSlow_op_to_primitive(Instruction* currentInstruction, Vector<SlowC
void JIT::emit_op_strcat(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_strcat);
- stubCall.addArgument(Imm32(currentInstruction[2].u.operand));
- stubCall.addArgument(Imm32(currentInstruction[3].u.operand));
+ stubCall.addArgument(TrustedImm32(currentInstruction[2].u.operand));
+ stubCall.addArgument(TrustedImm32(currentInstruction[3].u.operand));
stubCall.call(currentInstruction[1].u.operand);
}
@@ -716,7 +716,7 @@ void JIT::emit_op_resolve_base(Instruction* currentInstruction)
void JIT::emit_op_ensure_property_exists(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_ensure_property_exists);
- stubCall.addArgument(Imm32(currentInstruction[1].u.operand));
+ stubCall.addArgument(TrustedImm32(currentInstruction[1].u.operand));
stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
stubCall.call(currentInstruction[1].u.operand);
}
@@ -725,7 +725,7 @@ void JIT::emit_op_resolve_skip(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_resolve_skip);
stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
- stubCall.addArgument(Imm32(currentInstruction[3].u.operand));
+ stubCall.addArgument(TrustedImm32(currentInstruction[3].u.operand));
stubCall.callWithValueProfiling(currentInstruction[1].u.operand);
}
@@ -766,7 +766,7 @@ void JIT::emitSlow_op_resolve_global(Instruction* currentInstruction, Vector<Slo
linkSlowCase(iter);
JITStubCall stubCall(this, cti_op_resolve_global);
stubCall.addArgument(TrustedImmPtr(ident));
- stubCall.addArgument(Imm32(currentIndex));
+ stubCall.addArgument(TrustedImm32(currentIndex));
stubCall.callWithValueProfiling(dst);
}
@@ -817,7 +817,7 @@ void JIT::emitSlow_op_jfalse(Instruction* currentInstruction, Vector<SlowCaseEnt
if (supportsFloatingPoint()) {
// regT1 contains the tag from the hot path.
- Jump notNumber = branch32(Above, regT1, Imm32(JSValue::LowestTag));
+ Jump notNumber = branch32(Above, regT1, TrustedImm32(JSValue::LowestTag));
emitLoadDouble(cond, fpRegT0);
emitJumpSlowToHot(branchDoubleZeroOrNaN(fpRegT0, fpRegT1), target);
@@ -853,7 +853,7 @@ void JIT::emitSlow_op_jtrue(Instruction* currentInstruction, Vector<SlowCaseEntr
if (supportsFloatingPoint()) {
// regT1 contains the tag from the hot path.
- Jump notNumber = branch32(Above, regT1, Imm32(JSValue::LowestTag));
+ Jump notNumber = branch32(Above, regT1, TrustedImm32(JSValue::LowestTag));
emitLoadDouble(cond, fpRegT0);
emitJumpSlowToHot(branchDoubleNonZero(fpRegT0, fpRegT1), target);
@@ -1164,7 +1164,7 @@ void JIT::emit_op_resolve_with_base(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_resolve_with_base);
stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[3].u.operand)));
- stubCall.addArgument(Imm32(currentInstruction[1].u.operand));
+ stubCall.addArgument(TrustedImm32(currentInstruction[1].u.operand));
stubCall.callWithValueProfiling(currentInstruction[2].u.operand);
}
@@ -1172,7 +1172,7 @@ void JIT::emit_op_resolve_with_this(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_resolve_with_this);
stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[3].u.operand)));
- stubCall.addArgument(Imm32(currentInstruction[1].u.operand));
+ stubCall.addArgument(TrustedImm32(currentInstruction[1].u.operand));
stubCall.callWithValueProfiling(currentInstruction[2].u.operand);
}
@@ -1364,7 +1364,7 @@ void JIT::emit_op_catch(Instruction* currentInstruction)
void JIT::emit_op_jmp_scopes(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_jmp_scopes);
- stubCall.addArgument(Imm32(currentInstruction[1].u.operand));
+ stubCall.addArgument(TrustedImm32(currentInstruction[1].u.operand));
stubCall.call();
addJump(jump(), currentInstruction[2].u.operand);
}
@@ -1382,7 +1382,7 @@ void JIT::emit_op_switch_imm(Instruction* currentInstruction)
JITStubCall stubCall(this, cti_op_switch_imm);
stubCall.addArgument(scrutinee);
- stubCall.addArgument(Imm32(tableIndex));
+ stubCall.addArgument(TrustedImm32(tableIndex));
stubCall.call();
jump(regT0);
}
@@ -1400,7 +1400,7 @@ void JIT::emit_op_switch_char(Instruction* currentInstruction)
JITStubCall stubCall(this, cti_op_switch_char);
stubCall.addArgument(scrutinee);
- stubCall.addArgument(Imm32(tableIndex));
+ stubCall.addArgument(TrustedImm32(tableIndex));
stubCall.call();
jump(regT0);
}
@@ -1417,7 +1417,7 @@ void JIT::emit_op_switch_string(Instruction* currentInstruction)
JITStubCall stubCall(this, cti_op_switch_string);
stubCall.addArgument(scrutinee);
- stubCall.addArgument(Imm32(tableIndex));
+ stubCall.addArgument(TrustedImm32(tableIndex));
stubCall.call();
jump(regT0);
}
diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
index 1ee2915dc..19abdbd89 100644
--- a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
+++ b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
@@ -57,7 +57,7 @@ void JIT::emit_op_put_by_index(Instruction* currentInstruction)
JITStubCall stubCall(this, cti_op_put_by_index);
stubCall.addArgument(base);
- stubCall.addArgument(Imm32(property));
+ stubCall.addArgument(TrustedImm32(property));
stubCall.addArgument(value);
stubCall.call();
}
diff --git a/Source/JavaScriptCore/jit/JITStubCall.h b/Source/JavaScriptCore/jit/JITStubCall.h
index 51401a77f..a525ff227 100644
--- a/Source/JavaScriptCore/jit/JITStubCall.h
+++ b/Source/JavaScriptCore/jit/JITStubCall.h
@@ -104,12 +104,24 @@ namespace JSC {
m_jit->poke(argument, m_stackIndex);
m_stackIndex += stackIndexStep;
}
+
+ void addArgument(JIT::Imm32 argument)
+ {
+ m_jit->poke(argument, m_stackIndex);
+ m_stackIndex += stackIndexStep;
+ }
void addArgument(JIT::TrustedImmPtr argument)
{
m_jit->poke(argument, m_stackIndex);
m_stackIndex += stackIndexStep;
}
+
+ void addArgument(JIT::ImmPtr argument)
+ {
+ m_jit->poke(argument, m_stackIndex);
+ m_stackIndex += stackIndexStep;
+ }
void addArgument(JIT::RegisterID argument)
{
diff --git a/Source/JavaScriptCore/jit/JITStubs.cpp b/Source/JavaScriptCore/jit/JITStubs.cpp
index a0a816505..eebe90427 100644
--- a/Source/JavaScriptCore/jit/JITStubs.cpp
+++ b/Source/JavaScriptCore/jit/JITStubs.cpp
@@ -43,7 +43,7 @@
#include "ExceptionHelpers.h"
#include "GetterSetter.h"
#include "Heap.h"
-#include "InlineASM.h"
+#include <wtf/InlineASM.h>
#include "JIT.h"
#include "JITExceptions.h"
#include "JSActivation.h"
@@ -1929,12 +1929,16 @@ DEFINE_STUB_FUNCTION(void, optimize_from_loop)
CallFrame* callFrame = stackFrame.callFrame;
CodeBlock* codeBlock = callFrame->codeBlock();
- unsigned bytecodeIndex = stackFrame.args[0].int32();
+ unsigned bytecodeIndex = stackFrame.args[0].int32();
+
#if ENABLE(JIT_VERBOSE_OSR)
dataLog("%p: Entered optimize_from_loop with executeCounter = %d, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u\n", codeBlock, codeBlock->jitExecuteCounter(), codeBlock->reoptimizationRetryCounter(), codeBlock->optimizationDelayCounter());
#endif
+ if (!codeBlock->checkIfOptimizationThresholdReached())
+ return;
+
if (codeBlock->hasOptimizedReplacement()) {
#if ENABLE(JIT_VERBOSE_OSR)
dataLog("Considering loop OSR into %p(%p) with success/fail %u/%u.\n", codeBlock, codeBlock->replacement(), codeBlock->replacement()->speculativeSuccessCounter(), codeBlock->replacement()->speculativeFailCounter());
@@ -2033,6 +2037,9 @@ DEFINE_STUB_FUNCTION(void, optimize_from_ret)
dataLog("Entered optimize_from_ret with executeCounter = %d, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u\n", codeBlock->jitExecuteCounter(), codeBlock->reoptimizationRetryCounter(), codeBlock->optimizationDelayCounter());
#endif
+ if (!codeBlock->checkIfOptimizationThresholdReached())
+ return;
+
if (codeBlock->hasOptimizedReplacement()) {
#if ENABLE(JIT_VERBOSE_OSR)
dataLog("Returning from old JIT call frame with optimized replacement %p(%p), with success/fail %u/%u", codeBlock, codeBlock->replacement(), codeBlock->replacement()->speculativeSuccessCounter(), codeBlock->replacement()->speculativeFailCounter());
@@ -2546,7 +2553,7 @@ DEFINE_STUB_FUNCTION(void, op_put_by_val)
if (jsArray->canSetIndex(i))
jsArray->setIndex(*globalData, i, value);
else
- JSArray::putByIndex(jsArray, callFrame, i, value);
+ JSArray::putByIndex(jsArray, callFrame, i, value, callFrame->codeBlock()->isStrictMode());
} else if (isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
JSByteArray* jsByteArray = asByteArray(baseValue);
ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_put_by_val_byte_array));
@@ -2561,9 +2568,9 @@ DEFINE_STUB_FUNCTION(void, op_put_by_val)
}
}
- baseValue.put(callFrame, i, value);
+ baseValue.putByIndex(callFrame, i, value, callFrame->codeBlock()->isStrictMode());
} else
- baseValue.put(callFrame, i, value);
+ baseValue.putByIndex(callFrame, i, value, callFrame->codeBlock()->isStrictMode());
} else {
Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
if (!stackFrame.globalData->exception) { // Don't put to an object if toString threw an exception.
@@ -2604,7 +2611,7 @@ DEFINE_STUB_FUNCTION(void, op_put_by_val_byte_array)
if (!isJSByteArray(baseValue))
ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_put_by_val));
- baseValue.put(callFrame, i, value);
+ baseValue.putByIndex(callFrame, i, value, callFrame->codeBlock()->isStrictMode());
} else {
Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
if (!stackFrame.globalData->exception) { // Don't put to an object if toString threw an exception.
@@ -3036,19 +3043,6 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_rshift)
return JSValue::encode(result);
}
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_bitnot)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue src = stackFrame.args[0].jsValue();
-
- ASSERT(!src.isInt32());
- CallFrame* callFrame = stackFrame.callFrame;
- JSValue result = jsNumber(~src.toInt32(callFrame));
- CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(result);
-}
-
DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_with_base)
{
STUB_INIT_STACK_FRAME(stackFrame);
@@ -3307,7 +3301,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_stricteq)
JSValue src1 = stackFrame.args[0].jsValue();
JSValue src2 = stackFrame.args[1].jsValue();
-
+
bool result = JSValue::strictEqual(stackFrame.callFrame, src1, src2);
CHECK_FOR_EXCEPTION_AT_END();
return JSValue::encode(jsBoolean(result));
@@ -3408,7 +3402,9 @@ DEFINE_STUB_FUNCTION(void, op_put_by_index)
CallFrame* callFrame = stackFrame.callFrame;
unsigned property = stackFrame.args[1].int32();
- stackFrame.args[0].jsValue().put(callFrame, property, stackFrame.args[2].jsValue());
+ JSValue arrayValue = stackFrame.args[0].jsValue();
+ ASSERT(isJSArray(arrayValue));
+ asArray(arrayValue)->putDirectIndex(callFrame, property, stackFrame.args[2].jsValue(), false);
}
DEFINE_STUB_FUNCTION(void*, op_switch_imm)
diff --git a/Source/JavaScriptCore/jit/JITStubs.h b/Source/JavaScriptCore/jit/JITStubs.h
index 890d99747..49f666465 100644
--- a/Source/JavaScriptCore/jit/JITStubs.h
+++ b/Source/JavaScriptCore/jit/JITStubs.h
@@ -32,6 +32,7 @@
#include "CallData.h"
#include "Intrinsic.h"
+#include "LowLevelInterpreter.h"
#include "MacroAssemblerCodeRef.h"
#include "Register.h"
#include "ThunkGenerators.h"
@@ -39,6 +40,8 @@
namespace JSC {
+#if ENABLE(JIT)
+
struct StructureStubInfo;
class CodeBlock;
@@ -261,8 +264,6 @@ namespace JSC {
#define JITSTACKFRAME_ARGS_INDEX (OBJECT_OFFSETOF(JITStackFrame, args) / sizeof(void*))
-#if ENABLE(JIT)
-
#define STUB_ARGS_DECLARATION void** args
#define STUB_ARGS (args)
@@ -306,8 +307,22 @@ namespace JSC {
MacroAssemblerCodePtr ctiVirtualConstructLink() { return m_trampolineStructure.ctiVirtualConstructLink; }
MacroAssemblerCodePtr ctiVirtualCall() { return m_trampolineStructure.ctiVirtualCall; }
MacroAssemblerCodePtr ctiVirtualConstruct() { return m_trampolineStructure.ctiVirtualConstruct; }
- MacroAssemblerCodePtr ctiNativeCall() { return m_trampolineStructure.ctiNativeCall; }
- MacroAssemblerCodePtr ctiNativeConstruct() { return m_trampolineStructure.ctiNativeConstruct; }
+ MacroAssemblerCodePtr ctiNativeCall()
+ {
+#if ENABLE(LLINT)
+ if (!m_executableMemory)
+ return MacroAssemblerCodePtr::createLLIntCodePtr(llint_native_call_trampoline);
+#endif
+ return m_trampolineStructure.ctiNativeCall;
+ }
+ MacroAssemblerCodePtr ctiNativeConstruct()
+ {
+#if ENABLE(LLINT)
+ if (!m_executableMemory)
+ return MacroAssemblerCodePtr::createLLIntCodePtr(llint_native_construct_trampoline);
+#endif
+ return m_trampolineStructure.ctiNativeConstruct;
+ }
MacroAssemblerCodePtr ctiSoftModulo() { return m_trampolineStructure.ctiSoftModulo; }
MacroAssemblerCodeRef ctiStub(JSGlobalData*, ThunkGenerator);
@@ -330,7 +345,6 @@ namespace JSC {
extern "C" {
EncodedJSValue JIT_STUB cti_op_add(STUB_ARGS_DECLARATION);
EncodedJSValue JIT_STUB cti_op_bitand(STUB_ARGS_DECLARATION);
- EncodedJSValue JIT_STUB cti_op_bitnot(STUB_ARGS_DECLARATION);
EncodedJSValue JIT_STUB cti_op_bitor(STUB_ARGS_DECLARATION);
EncodedJSValue JIT_STUB cti_op_bitxor(STUB_ARGS_DECLARATION);
EncodedJSValue JIT_STUB cti_op_call_NotJSFunction(STUB_ARGS_DECLARATION);
diff --git a/Source/JavaScriptCore/jit/ThunkGenerators.cpp b/Source/JavaScriptCore/jit/ThunkGenerators.cpp
index 099796986..371aff2f9 100644
--- a/Source/JavaScriptCore/jit/ThunkGenerators.cpp
+++ b/Source/JavaScriptCore/jit/ThunkGenerators.cpp
@@ -27,7 +27,7 @@
#include "ThunkGenerators.h"
#include "CodeBlock.h"
-#include "InlineASM.h"
+#include <wtf/InlineASM.h>
#include "SpecializedThunkJIT.h"
#include <wtf/text/StringImpl.h>
diff --git a/Source/JavaScriptCore/jsc.cpp b/Source/JavaScriptCore/jsc.cpp
index 9f207c510..3d9d1d33e 100644
--- a/Source/JavaScriptCore/jsc.cpp
+++ b/Source/JavaScriptCore/jsc.cpp
@@ -206,9 +206,9 @@ protected:
addConstructableFunction(globalData, "Float64Array", constructJSFloat64Array, 1);
#endif
- JSObject* array = constructEmptyArray(globalExec());
+ JSArray* array = constructEmptyArray(globalExec());
for (size_t i = 0; i < arguments.size(); ++i)
- array->methodTable()->putByIndex(array, globalExec(), i, jsString(globalExec(), arguments[i]));
+ array->putDirectIndex(globalExec(), i, jsString(globalExec(), arguments[i]), false);
putDirect(globalData, Identifier(globalExec(), "arguments"), array);
}
diff --git a/Source/JavaScriptCore/llint/LLIntData.cpp b/Source/JavaScriptCore/llint/LLIntData.cpp
index c0fe78142..983a7d706 100644
--- a/Source/JavaScriptCore/llint/LLIntData.cpp
+++ b/Source/JavaScriptCore/llint/LLIntData.cpp
@@ -72,6 +72,7 @@ void Data::performAssertions(JSGlobalData& globalData)
ASSERT(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag) == 4);
ASSERT(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload) == 0);
#endif
+#if USE(JSVALUE32_64)
ASSERT(JSValue::Int32Tag == -1);
ASSERT(JSValue::BooleanTag == -2);
ASSERT(JSValue::NullTag == -3);
@@ -80,12 +81,26 @@ void Data::performAssertions(JSGlobalData& globalData)
ASSERT(JSValue::EmptyValueTag == -6);
ASSERT(JSValue::DeletedValueTag == -7);
ASSERT(JSValue::LowestTag == -7);
+#else
+ ASSERT(TagBitTypeOther == 0x2);
+ ASSERT(TagBitBool == 0x4);
+ ASSERT(TagBitUndefined == 0x8);
+ ASSERT(ValueEmpty == 0x0);
+ ASSERT(ValueFalse == (TagBitTypeOther | TagBitBool));
+ ASSERT(ValueTrue == (TagBitTypeOther | TagBitBool | 1));
+ ASSERT(ValueUndefined == (TagBitTypeOther | TagBitUndefined));
+ ASSERT(ValueNull == TagBitTypeOther);
+#endif
ASSERT(StringType == 5);
ASSERT(ObjectType == 13);
ASSERT(MasqueradesAsUndefined == 1);
ASSERT(ImplementsHasInstance == 2);
ASSERT(ImplementsDefaultHasInstance == 8);
+#if USE(JSVALUE64)
+ ASSERT(&globalData.heap.allocatorForObjectWithoutDestructor(sizeof(JSFinalObject)) - &globalData.heap.firstAllocatorWithoutDestructors() == 1);
+#else
ASSERT(&globalData.heap.allocatorForObjectWithoutDestructor(sizeof(JSFinalObject)) - &globalData.heap.firstAllocatorWithoutDestructors() == 3);
+#endif
ASSERT(FirstConstantRegisterIndex == 0x40000000);
ASSERT(GlobalCode == 0);
ASSERT(EvalCode == 1);
diff --git a/Source/JavaScriptCore/llint/LLIntEntrypoints.cpp b/Source/JavaScriptCore/llint/LLIntEntrypoints.cpp
index f610f4b4c..dd7d9433d 100644
--- a/Source/JavaScriptCore/llint/LLIntEntrypoints.cpp
+++ b/Source/JavaScriptCore/llint/LLIntEntrypoints.cpp
@@ -30,8 +30,10 @@
#include "JITCode.h"
#include "JSGlobalData.h"
+#include "JSObject.h"
#include "LLIntThunks.h"
#include "LowLevelInterpreter.h"
+#include "ScopeChain.h"
namespace JSC { namespace LLInt {
@@ -39,14 +41,14 @@ void getFunctionEntrypoint(JSGlobalData& globalData, CodeSpecializationKind kind
{
if (!globalData.canUseJIT()) {
if (kind == CodeForCall) {
- jitCode = JITCode::HostFunction(MacroAssemblerCodeRef::createSelfManagedCodeRef(MacroAssemblerCodePtr(bitwise_cast<void*>(&llint_function_for_call_prologue))));
- arityCheck = MacroAssemblerCodePtr(bitwise_cast<void*>(&llint_function_for_call_arity_check));
+ jitCode = JITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_function_for_call_prologue), JITCode::InterpreterThunk);
+ arityCheck = MacroAssemblerCodePtr::createLLIntCodePtr(llint_function_for_call_arity_check);
return;
}
ASSERT(kind == CodeForConstruct);
- jitCode = JITCode::HostFunction(MacroAssemblerCodeRef::createSelfManagedCodeRef(MacroAssemblerCodePtr(bitwise_cast<void*>(&llint_function_for_construct_prologue))));
- arityCheck = MacroAssemblerCodePtr(bitwise_cast<void*>(&llint_function_for_construct_arity_check));
+ jitCode = JITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_function_for_construct_prologue), JITCode::InterpreterThunk);
+ arityCheck = MacroAssemblerCodePtr::createLLIntCodePtr(llint_function_for_construct_arity_check);
return;
}
@@ -64,7 +66,7 @@ void getFunctionEntrypoint(JSGlobalData& globalData, CodeSpecializationKind kind
void getEvalEntrypoint(JSGlobalData& globalData, JITCode& jitCode)
{
if (!globalData.canUseJIT()) {
- jitCode = JITCode::HostFunction(MacroAssemblerCodeRef::createSelfManagedCodeRef(MacroAssemblerCodePtr(bitwise_cast<void*>(&llint_eval_prologue))));
+ jitCode = JITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_eval_prologue), JITCode::InterpreterThunk);
return;
}
@@ -74,7 +76,7 @@ void getEvalEntrypoint(JSGlobalData& globalData, JITCode& jitCode)
void getProgramEntrypoint(JSGlobalData& globalData, JITCode& jitCode)
{
if (!globalData.canUseJIT()) {
- jitCode = JITCode::HostFunction(MacroAssemblerCodeRef::createSelfManagedCodeRef(MacroAssemblerCodePtr(bitwise_cast<void*>(&llint_program_prologue))));
+ jitCode = JITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_program_prologue), JITCode::InterpreterThunk);
return;
}
diff --git a/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h b/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h
index 9fe86fac4..2539ee9b3 100644
--- a/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h
+++ b/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h
@@ -43,6 +43,18 @@
#define OFFLINE_ASM_ARMv7 0
#endif
+#if CPU(X86_64)
+#define OFFLINE_ASM_X86_64 1
+#else
+#define OFFLINE_ASM_X86_64 0
+#endif
+
+#if USE(JSVALUE64)
+#define OFFLINE_ASM_JSVALUE64 1
+#else
+#define OFFLINE_ASM_JSVALUE64 0
+#endif
+
#if !ASSERT_DISABLED
#define OFFLINE_ASM_ASSERT_ENABLED 1
#else
@@ -73,6 +85,12 @@
#define OFFLINE_ASM_ALWAYS_ALLOCATE_SLOW 0
#endif
+#if ENABLE(VALUE_PROFILER)
+#define OFFLINE_ASM_VALUE_PROFILER 1
+#else
+#define OFFLINE_ASM_VALUE_PROFILER 0
+#endif
+
#if CPU(ARM_THUMB2)
#define OFFLINE_ASM_GLOBAL_LABEL(label) \
".globl " SYMBOL_STRING(label) "\n" \
diff --git a/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp b/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp
index 5b76cd521..f863cb218 100644
--- a/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp
+++ b/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp
@@ -61,6 +61,7 @@ public:
const unsigned* LLIntOffsetsExtractor::dummy()
{
+#if ENABLE(JIT)
// This is a file generated by offlineasm/generate_offsets_extractor.rb, and contains code
// to create a table of offsets, sizes, and a header identifying what combination of
// Platform.h macros we have set. We include it inside of a method on LLIntOffsetsExtractor
@@ -69,6 +70,9 @@ const unsigned* LLIntOffsetsExtractor::dummy()
// compiler to kindly step aside and yield to our best intentions.
#include "LLIntDesiredOffsets.h"
return extractorTable;
+#else
+ return 0;
+#endif
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
index 3203d25d2..b6bb664bc 100644
--- a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
+++ b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
@@ -65,16 +65,7 @@ namespace JSC { namespace LLInt {
#define LLINT_OP_C(index) (exec->r(pc[index].u.operand))
#define LLINT_RETURN_TWO(first, second) do { \
- union { \
- struct { \
- void* a; \
- void* b; \
- } pair; \
- int64_t i; \
- } __rt_u; \
- __rt_u.pair.a = first; \
- __rt_u.pair.b = second; \
- return __rt_u.i; \
+ return encodeResult(first, second); \
} while (false)
#define LLINT_END_IMPL() LLINT_RETURN_TWO(pc, exec)
@@ -114,6 +105,7 @@ namespace JSC { namespace LLInt {
LLINT_END_IMPL(); \
} while (false)
+#if ENABLE(VALUE_PROFILER)
#define LLINT_RETURN_PROFILED(opcode, value) do { \
JSValue __rp_returnValue = (value); \
LLINT_CHECK_EXCEPTION(); \
@@ -122,6 +114,9 @@ namespace JSC { namespace LLInt {
JSValue::encode(__rp_returnValue); \
LLINT_END_IMPL(); \
} while (false)
+#else // ENABLE(VALUE_PROFILER)
+#define LLINT_RETURN_PROFILED(opcode, value) LLINT_RETURN(value)
+#endif // ENABLE(VALUE_PROFILER)
#define LLINT_CALL_END_IMPL(exec, callTarget) LLINT_RETURN_TWO((callTarget), (exec))
@@ -163,7 +158,6 @@ extern "C" SlowPathReturnType llint_trace_operand(ExecState* exec, Instruction*
extern "C" SlowPathReturnType llint_trace_value(ExecState* exec, Instruction* pc, int fromWhere, int operand)
{
- LLINT_BEGIN();
JSValue value = LLINT_OP_C(operand).jsValue();
union {
struct {
@@ -184,14 +178,13 @@ extern "C" SlowPathReturnType llint_trace_value(ExecState* exec, Instruction* pc
u.bits.tag,
u.bits.payload,
value.description());
- LLINT_END();
+ LLINT_END_IMPL();
}
LLINT_SLOW_PATH_DECL(trace_prologue)
{
- LLINT_BEGIN();
dataLog("%p / %p: in prologue.\n", exec->codeBlock(), exec);
- LLINT_END();
+ LLINT_END_IMPL();
}
static void traceFunctionPrologue(ExecState* exec, const char* comment, CodeSpecializationKind kind)
@@ -207,54 +200,52 @@ static void traceFunctionPrologue(ExecState* exec, const char* comment, CodeSpec
LLINT_SLOW_PATH_DECL(trace_prologue_function_for_call)
{
- LLINT_BEGIN();
traceFunctionPrologue(exec, "call prologue", CodeForCall);
- LLINT_END();
+ LLINT_END_IMPL();
}
LLINT_SLOW_PATH_DECL(trace_prologue_function_for_construct)
{
- LLINT_BEGIN();
traceFunctionPrologue(exec, "construct prologue", CodeForConstruct);
- LLINT_END();
+ LLINT_END_IMPL();
}
LLINT_SLOW_PATH_DECL(trace_arityCheck_for_call)
{
- LLINT_BEGIN();
traceFunctionPrologue(exec, "call arity check", CodeForCall);
- LLINT_END();
+ LLINT_END_IMPL();
}
LLINT_SLOW_PATH_DECL(trace_arityCheck_for_construct)
{
- LLINT_BEGIN();
traceFunctionPrologue(exec, "construct arity check", CodeForConstruct);
- LLINT_END();
+ LLINT_END_IMPL();
}
LLINT_SLOW_PATH_DECL(trace)
{
- LLINT_BEGIN();
dataLog("%p / %p: executing bc#%zu, %s, scope %p\n",
exec->codeBlock(),
exec,
static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
opcodeNames[exec->globalData().interpreter->getOpcodeID(pc[0].u.opcode)],
exec->scopeChain());
- LLINT_END();
+ if (exec->globalData().interpreter->getOpcodeID(pc[0].u.opcode) == op_ret) {
+ dataLog("Will be returning to %p\n", exec->returnPC().value());
+ dataLog("The new cfr will be %p\n", exec->callerFrame());
+ }
+ LLINT_END_IMPL();
}
LLINT_SLOW_PATH_DECL(special_trace)
{
- LLINT_BEGIN();
dataLog("%p / %p: executing special case bc#%zu, op#%u, return PC is %p\n",
exec->codeBlock(),
exec,
static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
exec->globalData().interpreter->getOpcodeID(pc[0].u.opcode),
exec->returnPC().value());
- LLINT_END();
+ LLINT_END_IMPL();
}
inline bool shouldJIT(ExecState* exec)
@@ -263,6 +254,41 @@ inline bool shouldJIT(ExecState* exec)
return exec->globalData().canUseJIT();
}
+// Returns true if we should try to OSR.
+inline bool jitCompileAndSetHeuristics(CodeBlock* codeBlock, ExecState* exec)
+{
+ if (!codeBlock->checkIfJITThresholdReached()) {
+#if ENABLE(JIT_VERBOSE_OSR)
+ dataLog(" JIT threshold should be lifted.\n");
+#endif
+ return false;
+ }
+
+ CodeBlock::JITCompilationResult result = codeBlock->jitCompile(exec->globalData());
+ switch (result) {
+ case CodeBlock::AlreadyCompiled:
+#if ENABLE(JIT_VERBOSE_OSR)
+ dataLog(" Code was already compiled.\n");
+#endif
+ codeBlock->jitSoon();
+ return true;
+ case CodeBlock::CouldNotCompile:
+#if ENABLE(JIT_VERBOSE_OSR)
+ dataLog(" JIT compilation failed.\n");
+#endif
+ codeBlock->dontJITAnytimeSoon();
+ return false;
+ case CodeBlock::CompiledSuccessfully:
+#if ENABLE(JIT_VERBOSE_OSR)
+ dataLog(" JIT compilation successful.\n");
+#endif
+ codeBlock->jitSoon();
+ return true;
+ }
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
enum EntryKind { Prologue, ArityCheck };
static SlowPathReturnType entryOSR(ExecState* exec, Instruction* pc, CodeBlock* codeBlock, const char *name, EntryKind kind)
{
@@ -274,12 +300,9 @@ static SlowPathReturnType entryOSR(ExecState* exec, Instruction* pc, CodeBlock*
codeBlock->dontJITAnytimeSoon();
LLINT_RETURN_TWO(0, exec);
}
- if (!codeBlock->jitCompile(exec->globalData())) {
-#if ENABLE(JIT_VERBOSE_OSR)
- dataLog(" Code was already compiled.\n");
-#endif
- }
- codeBlock->jitSoon();
+ if (!jitCompileAndSetHeuristics(codeBlock, exec))
+ LLINT_RETURN_TWO(0, exec);
+
if (kind == Prologue)
LLINT_RETURN_TWO(codeBlock->getJITCode().executableAddressAtOffset(0), exec);
ASSERT(kind == ArityCheck);
@@ -324,12 +347,8 @@ LLINT_SLOW_PATH_DECL(loop_osr)
LLINT_RETURN_TWO(0, exec);
}
- if (!codeBlock->jitCompile(exec->globalData())) {
-#if ENABLE(JIT_VERBOSE_OSR)
- dataLog(" Code was already compiled.\n");
-#endif
- }
- codeBlock->jitSoon();
+ if (!jitCompileAndSetHeuristics(codeBlock, exec))
+ LLINT_RETURN_TWO(0, exec);
ASSERT(codeBlock->getJITType() == JITCode::BaselineJIT);
@@ -353,14 +372,9 @@ LLINT_SLOW_PATH_DECL(replace)
dataLog("%p: Entered replace with executeCounter = %d\n", codeBlock, codeBlock->llintExecuteCounter());
#endif
- if (shouldJIT(exec)) {
- if (!codeBlock->jitCompile(exec->globalData())) {
-#if ENABLE(JIT_VERBOSE_OSR)
- dataLog(" Code was already compiled.\n");
-#endif
- }
- codeBlock->jitSoon();
- } else
+ if (shouldJIT(exec))
+ jitCompileAndSetHeuristics(codeBlock, exec);
+ else
codeBlock->dontJITAnytimeSoon();
LLINT_END_IMPL();
}
@@ -664,12 +678,6 @@ LLINT_SLOW_PATH_DECL(slow_path_bitxor)
LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toInt32(exec) ^ LLINT_OP_C(3).jsValue().toInt32(exec)));
}
-LLINT_SLOW_PATH_DECL(slow_path_bitnot)
-{
- LLINT_BEGIN();
- LLINT_RETURN(jsNumber(~LLINT_OP_C(2).jsValue().toInt32(exec)));
-}
-
LLINT_SLOW_PATH_DECL(slow_path_check_has_instance)
{
LLINT_BEGIN();
@@ -873,8 +881,10 @@ LLINT_SLOW_PATH_DECL(slow_path_get_by_id)
pc[5].u.operand = slot.cachedOffset() * sizeof(JSValue);
}
}
-
+
+#if ENABLE(VALUE_PROFILER)
pc[OPCODE_LENGTH(op_get_by_id) - 1].u.profile->m_buckets[0] = JSValue::encode(result);
+#endif
LLINT_END();
}
@@ -1023,7 +1033,7 @@ LLINT_SLOW_PATH_DECL(slow_path_put_by_val)
if (jsArray->canSetIndex(i))
jsArray->setIndex(globalData, i, value);
else
- JSArray::putByIndex(jsArray, exec, i, value);
+ JSArray::putByIndex(jsArray, exec, i, value, exec->codeBlock()->isStrictMode());
LLINT_END();
}
if (isJSByteArray(baseValue)
@@ -1038,7 +1048,7 @@ LLINT_SLOW_PATH_DECL(slow_path_put_by_val)
LLINT_END();
}
}
- baseValue.put(exec, i, value);
+ baseValue.putByIndex(exec, i, value, exec->codeBlock()->isStrictMode());
LLINT_END();
}
@@ -1078,7 +1088,9 @@ LLINT_SLOW_PATH_DECL(slow_path_del_by_val)
LLINT_SLOW_PATH_DECL(slow_path_put_by_index)
{
LLINT_BEGIN();
- LLINT_OP_C(1).jsValue().put(exec, pc[2].u.operand, LLINT_OP_C(3).jsValue());
+ JSValue arrayValue = LLINT_OP_C(1).jsValue();
+ ASSERT(isJSArray(arrayValue));
+ asArray(arrayValue)->putDirectIndex(exec, pc[2].u.operand, LLINT_OP_C(3).jsValue(), false);
LLINT_END();
}
@@ -1384,7 +1396,7 @@ LLINT_SLOW_PATH_DECL(slow_path_call_varargs)
execCallee->uncheckedR(RegisterFile::Callee) = calleeAsValue;
execCallee->setCallerFrame(exec);
- exec->uncheckedR(RegisterFile::ArgumentCount).tag() = bitwise_cast<int32_t>(pc + OPCODE_LENGTH(op_call_varargs));
+ exec->setCurrentVPC(pc + OPCODE_LENGTH(op_call_varargs));
return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
}
@@ -1402,7 +1414,7 @@ LLINT_SLOW_PATH_DECL(slow_path_call_eval)
execCallee->setScopeChain(exec->scopeChain());
execCallee->setReturnPC(bitwise_cast<Instruction*>(&llint_generic_return_point));
execCallee->setCodeBlock(0);
- exec->uncheckedR(RegisterFile::ArgumentCount).tag() = bitwise_cast<int32_t>(pc + OPCODE_LENGTH(op_call_eval));
+ exec->setCurrentVPC(pc + OPCODE_LENGTH(op_call_eval));
if (!isHostFunction(calleeAsValue, globalFuncEval))
return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
@@ -1553,6 +1565,13 @@ LLINT_SLOW_PATH_DECL(slow_path_profile_did_call)
LLINT_END();
}
+LLINT_SLOW_PATH_DECL(throw_from_native_call)
+{
+ LLINT_BEGIN();
+ ASSERT(globalData.exception);
+ LLINT_END();
+}
+
} } // namespace JSC::LLInt
#endif // ENABLE(LLINT)
diff --git a/Source/JavaScriptCore/llint/LLIntSlowPaths.h b/Source/JavaScriptCore/llint/LLIntSlowPaths.h
index fe684d306..334070a07 100644
--- a/Source/JavaScriptCore/llint/LLIntSlowPaths.h
+++ b/Source/JavaScriptCore/llint/LLIntSlowPaths.h
@@ -38,8 +38,40 @@ struct Instruction;
namespace LLInt {
+#if USE(JSVALUE64)
+struct SlowPathReturnType {
+ void* a;
+ void* b;
+
+ SlowPathReturnType(void* a, void* b)
+ : a(a)
+ , b(b)
+ {
+ }
+};
+
+inline SlowPathReturnType encodeResult(void* a, void* b)
+{
+ return SlowPathReturnType(a, b);
+}
+#else
typedef int64_t SlowPathReturnType;
+inline SlowPathReturnType encodeResult(void* a, void* b)
+{
+ union {
+ struct {
+ void* a;
+ void* b;
+ } pair;
+ int64_t i;
+ } u;
+ u.pair.a = a;
+ u.pair.b = b;
+ return u.i;
+}
+#endif
+
extern "C" SlowPathReturnType llint_trace_operand(ExecState*, Instruction*, int fromWhere, int operand);
extern "C" SlowPathReturnType llint_trace_value(ExecState*, Instruction*, int fromWhere, int operand);
@@ -97,7 +129,6 @@ LLINT_SLOW_PATH_DECL(slow_path_urshift);
LLINT_SLOW_PATH_DECL(slow_path_bitand);
LLINT_SLOW_PATH_DECL(slow_path_bitor);
LLINT_SLOW_PATH_DECL(slow_path_bitxor);
-LLINT_SLOW_PATH_DECL(slow_path_bitnot);
LLINT_SLOW_PATH_DECL(slow_path_check_has_instance);
LLINT_SLOW_PATH_DECL(slow_path_instanceof);
LLINT_SLOW_PATH_DECL(slow_path_typeof);
@@ -162,6 +193,7 @@ LLINT_SLOW_PATH_DECL(slow_path_throw_reference_error);
LLINT_SLOW_PATH_DECL(slow_path_debug);
LLINT_SLOW_PATH_DECL(slow_path_profile_will_call);
LLINT_SLOW_PATH_DECL(slow_path_profile_did_call);
+LLINT_SLOW_PATH_DECL(throw_from_native_call);
} } // namespace JSC::LLInt
diff --git a/Source/JavaScriptCore/llint/LLIntThunks.cpp b/Source/JavaScriptCore/llint/LLIntThunks.cpp
index ddb0c46c2..b4d026423 100644
--- a/Source/JavaScriptCore/llint/LLIntThunks.cpp
+++ b/Source/JavaScriptCore/llint/LLIntThunks.cpp
@@ -29,8 +29,10 @@
#if ENABLE(LLINT)
#include "JSInterfaceJIT.h"
+#include "JSObject.h"
#include "LinkBuffer.h"
#include "LowLevelInterpreter.h"
+#include "ScopeChain.h"
namespace JSC { namespace LLInt {
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
index a9f83f680..9af91bef2 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
@@ -21,54 +21,8 @@
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGE.
-
-# Crash course on the language that this is written in (which I just call
-# "assembly" even though it's more than that):
-#
-# - Mostly gas-style operand ordering. The last operand tends to be the
-# destination. So "a := b" is written as "mov b, a". But unlike gas,
-# comparisons are in-order, so "if (a < b)" is written as
-# "bilt a, b, ...".
-#
-# - "b" = byte, "h" = 16-bit word, "i" = 32-bit word, "p" = pointer.
-# Currently this is just 32-bit so "i" and "p" are interchangeable
-# except when an op supports one but not the other.
-#
-# - In general, valid operands for macro invocations and instructions are
-# registers (eg "t0"), addresses (eg "4[t0]"), base-index addresses
-# (eg "7[t0, t1, 2]"), absolute addresses (eg "0xa0000000[]"), or labels
-# (eg "_foo" or ".foo"). Macro invocations can also take anonymous
-# macros as operands. Instructions cannot take anonymous macros.
-#
-# - Labels must have names that begin with either "_" or ".". A "." label
-# is local and gets renamed before code gen to minimize namespace
-# pollution. A "_" label is an extern symbol (i.e. ".globl"). The "_"
-# may or may not be removed during code gen depending on whether the asm
-# conventions for C name mangling on the target platform mandate a "_"
-# prefix.
-#
-# - A "macro" is a lambda expression, which may be either anonymous or
-# named. But this has caveats. "macro" can take zero or more arguments,
-# which may be macros or any valid operands, but it can only return
-# code. But you can do Turing-complete things via continuation passing
-# style: "macro foo (a, b) b(a) end foo(foo, foo)". Actually, don't do
-# that, since you'll just crash the assembler.
-#
-# - An "if" is a conditional on settings. Any identifier supplied in the
-# predicate of an "if" is assumed to be a #define that is available
-# during code gen. So you can't use "if" for computation in a macro, but
-# you can use it to select different pieces of code for different
-# platforms.
-#
-# - Arguments to macros follow lexical scoping rather than dynamic scoping.
-# Const's also follow lexical scoping and may override (hide) arguments
-# or other consts. All variables (arguments and constants) can be bound
-# to operands. Additionally, arguments (but not constants) can be bound
-# to macros.
-
-
-# Below we have a bunch of constant declarations. Each constant must have
-# a corresponding ASSERT() in LLIntData.cpp.
+# First come the common protocols that both interpreters use. Note that each
+# of these must have an ASSERT() in LLIntData.cpp
# These declarations must match interpreter/RegisterFile.h.
const CallFrameHeaderSize = 48
@@ -81,10 +35,24 @@ const CodeBlock = -8
const ThisArgumentOffset = -CallFrameHeaderSize - 8
-# Declare some aliases for the registers we will use.
-const PC = t4
+# Some register conventions.
+if JSVALUE64
+ # - Use a pair of registers to represent the PC: one register for the
+ # base of the register file, and one register for the index.
+ # - The PC base (or PB for short) should be stored in the csr. It will
+ # get clobbered on calls to other JS code, but will get saved on calls
+ # to C functions.
+ # - C calls are still given the Instruction* rather than the PC index.
+ # This requires an add before the call, and a sub after.
+ const PC = t4
+ const PB = t6
+ const tagTypeNumber = csr1
+ const tagMask = csr2
+else
+ const PC = t4
+end
-# Offsets needed for reasoning about value representation.
+# Constants for reasoning about value representation.
if BIG_ENDIAN
const TagOffset = 0
const PayloadOffset = 4
@@ -93,16 +61,6 @@ else
const PayloadOffset = 0
end
-# Value representation constants.
-const Int32Tag = -1
-const BooleanTag = -2
-const NullTag = -3
-const UndefinedTag = -4
-const CellTag = -5
-const EmptyValueTag = -6
-const DeletedValueTag = -7
-const LowestTag = DeletedValueTag
-
# Type constants.
const StringType = 5
const ObjectType = 13
@@ -112,9 +70,6 @@ const MasqueradesAsUndefined = 1
const ImplementsHasInstance = 2
const ImplementsDefaultHasInstance = 8
-# Heap allocation constants.
-const JSFinalObjectSizeClassIndex = 3
-
# Bytecode operand constants.
const FirstConstantRegisterIndex = 0x40000000
@@ -126,14 +81,27 @@ const FunctionCode = 2
# The interpreter steals the tag word of the argument count.
const LLIntReturnPC = ArgumentCount + TagOffset
-# This must match wtf/Vector.h.
-const VectorSizeOffset = 0
-const VectorBufferOffset = 4
-
# String flags.
const HashFlags8BitBuffer = 64
-# Utilities
+# Allocation constants
+if JSVALUE64
+ const JSFinalObjectSizeClassIndex = 1
+else
+ const JSFinalObjectSizeClassIndex = 3
+end
+
+# This must match wtf/Vector.h
+if JSVALUE64
+ const VectorSizeOffset = 0
+ const VectorBufferOffset = 8
+else
+ const VectorSizeOffset = 0
+ const VectorBufferOffset = 4
+end
+
+
+# Some common utilities.
macro crash()
storei 0, 0xbbadbeef[]
move 0, t0
@@ -151,7 +119,7 @@ end
macro preserveReturnAddressAfterCall(destinationRegister)
if ARMv7
move lr, destinationRegister
- elsif X86
+ elsif X86 or X86_64
pop destinationRegister
else
error
@@ -161,109 +129,23 @@ end
macro restoreReturnAddressBeforeReturn(sourceRegister)
if ARMv7
move sourceRegister, lr
- elsif X86
+ elsif X86 or X86_64
push sourceRegister
else
error
end
end
-macro dispatch(advance)
- addp advance * 4, PC
- jmp [PC]
-end
-
-macro dispatchBranchWithOffset(pcOffset)
- lshifti 2, pcOffset
- addp pcOffset, PC
- jmp [PC]
-end
-
-macro dispatchBranch(pcOffset)
- loadi pcOffset, t0
- dispatchBranchWithOffset(t0)
-end
-
-macro dispatchAfterCall()
- loadi ArgumentCount + TagOffset[cfr], PC
- jmp [PC]
-end
-
-macro cCall2(function, arg1, arg2)
- if ARMv7
- move arg1, t0
- move arg2, t1
- elsif X86
- poke arg1, 0
- poke arg2, 1
- else
- error
- end
- call function
-end
-
-# This barely works. arg3 and arg4 should probably be immediates.
-macro cCall4(function, arg1, arg2, arg3, arg4)
- if ARMv7
- move arg1, t0
- move arg2, t1
- move arg3, t2
- move arg4, t3
- elsif X86
- poke arg1, 0
- poke arg2, 1
- poke arg3, 2
- poke arg4, 3
- else
- error
- end
- call function
-end
-
-macro callSlowPath(slow_path)
- cCall2(slow_path, cfr, PC)
- move t0, PC
- move t1, cfr
-end
-
-# Debugging operation if you'd like to print an operand in the instruction stream. fromWhere
-# should be an immediate integer - any integer you like; use it to identify the place you're
-# debugging from. operand should likewise be an immediate, and should identify the operand
-# in the instruction stream you'd like to print out.
-macro traceOperand(fromWhere, operand)
- cCall4(_llint_trace_operand, cfr, PC, fromWhere, operand)
- move t0, PC
- move t1, cfr
-end
-
-# Debugging operation if you'd like to print the value of an operand in the instruction
-# stream. Same as traceOperand(), but assumes that the operand is a register, and prints its
-# value.
-macro traceValue(fromWhere, operand)
- cCall4(_llint_trace_value, cfr, PC, fromWhere, operand)
- move t0, PC
- move t1, cfr
-end
-
macro traceExecution()
if EXECUTION_TRACING
callSlowPath(_llint_trace)
end
end
-# Call a slow_path for call opcodes.
-macro callCallSlowPath(advance, slow_path, action)
- addp advance * 4, PC, t0
- storep t0, ArgumentCount + TagOffset[cfr]
- cCall2(slow_path, cfr, PC)
- move t1, cfr
- action(t0)
-end
-
-macro slowPathForCall(advance, slow_path)
+macro slowPathForCall(advance, slowPath)
callCallSlowPath(
advance,
- slow_path,
+ slowPath,
macro (callee)
call callee
dispatchAfterCall()
@@ -273,26 +155,12 @@ end
macro checkSwitchToJIT(increment, action)
if JIT_ENABLED
loadp CodeBlock[cfr], t0
- baddis increment, CodeBlock::m_llintExecuteCounter[t0], .continue
+ baddis increment, CodeBlock::m_llintExecuteCounter + ExecutionCounter::m_counter[t0], .continue
action()
.continue:
end
end
-macro checkSwitchToJITForLoop()
- checkSwitchToJIT(
- 1,
- macro ()
- storei PC, ArgumentCount + TagOffset[cfr]
- cCall2(_llint_loop_osr, cfr, PC)
- move t1, cfr
- btpz t0, .recover
- jmp t0
- .recover:
- loadi ArgumentCount + TagOffset[cfr], PC
- end)
-end
-
macro checkSwitchToJITForEpilogue()
checkSwitchToJIT(
10,
@@ -305,94 +173,6 @@ macro assertNotConstant(index)
assert(macro (ok) bilt index, FirstConstantRegisterIndex, ok end)
end
-# Index, tag, and payload must be different registers. Index is not
-# changed.
-macro loadConstantOrVariable(index, tag, payload)
- bigteq index, FirstConstantRegisterIndex, .constant
- loadi TagOffset[cfr, index, 8], tag
- loadi PayloadOffset[cfr, index, 8], payload
- jmp .done
-.constant:
- loadp CodeBlock[cfr], payload
- loadp CodeBlock::m_constantRegisters + VectorBufferOffset[payload], payload
- # There is a bit of evil here: if the index contains a value >= FirstConstantRegisterIndex,
- # then value << 3 will be equal to (value - FirstConstantRegisterIndex) << 3.
- loadp TagOffset[payload, index, 8], tag
- loadp PayloadOffset[payload, index, 8], payload
-.done:
-end
-
-# Index and payload may be the same register. Index may be clobbered.
-macro loadConstantOrVariable2Reg(index, tag, payload)
- bigteq index, FirstConstantRegisterIndex, .constant
- loadi TagOffset[cfr, index, 8], tag
- loadi PayloadOffset[cfr, index, 8], payload
- jmp .done
-.constant:
- loadp CodeBlock[cfr], tag
- loadp CodeBlock::m_constantRegisters + VectorBufferOffset[tag], tag
- # There is a bit of evil here: if the index contains a value >= FirstConstantRegisterIndex,
- # then value << 3 will be equal to (value - FirstConstantRegisterIndex) << 3.
- lshifti 3, index
- addp index, tag
- loadp PayloadOffset[tag], payload
- loadp TagOffset[tag], tag
-.done:
-end
-
-macro loadConstantOrVariablePayloadTagCustom(index, tagCheck, payload)
- bigteq index, FirstConstantRegisterIndex, .constant
- tagCheck(TagOffset[cfr, index, 8])
- loadi PayloadOffset[cfr, index, 8], payload
- jmp .done
-.constant:
- loadp CodeBlock[cfr], payload
- loadp CodeBlock::m_constantRegisters + VectorBufferOffset[payload], payload
- # There is a bit of evil here: if the index contains a value >= FirstConstantRegisterIndex,
- # then value << 3 will be equal to (value - FirstConstantRegisterIndex) << 3.
- tagCheck(TagOffset[payload, index, 8])
- loadp PayloadOffset[payload, index, 8], payload
-.done:
-end
-
-# Index and payload must be different registers. Index is not mutated. Use
-# this if you know what the tag of the variable should be. Doing the tag
-# test as part of loading the variable reduces register use, but may not
-# be faster than doing loadConstantOrVariable followed by a branch on the
-# tag.
-macro loadConstantOrVariablePayload(index, expectedTag, payload, slow)
- loadConstantOrVariablePayloadTagCustom(
- index,
- macro (actualTag) bineq actualTag, expectedTag, slow end,
- payload)
-end
-
-macro loadConstantOrVariablePayloadUnchecked(index, payload)
- loadConstantOrVariablePayloadTagCustom(
- index,
- macro (actualTag) end,
- payload)
-end
-
-macro writeBarrier(tag, payload)
- # Nothing to do, since we don't have a generational or incremental collector.
-end
-
-macro valueProfile(tag, payload, profile)
- if JIT_ENABLED
- storei tag, ValueProfile::m_buckets + TagOffset[profile]
- storei payload, ValueProfile::m_buckets + PayloadOffset[profile]
- end
-end
-
-
-# Indicate the beginning of LLInt.
-_llint_begin:
- crash()
-
-
-# Entrypoints into the interpreter
-
macro functionForCallCodeBlockGetter(targetRegister)
loadp Callee[cfr], targetRegister
loadp JSFunction::m_executable[targetRegister], targetRegister
@@ -429,7 +209,7 @@ macro prologue(codeBlockGetter, codeBlockSetter, osrSlowPath, traceSlowPath)
end
codeBlockGetter(t1)
if JIT_ENABLED
- baddis 5, CodeBlock::m_llintExecuteCounter[t1], .continue
+ baddis 5, CodeBlock::m_llintExecuteCounter + ExecutionCounter::m_counter[t1], .continue
cCall2(osrSlowPath, cfr, PC)
move t1, cfr
btpz t0, .recover
@@ -443,14 +223,18 @@ macro prologue(codeBlockGetter, codeBlockSetter, osrSlowPath, traceSlowPath)
codeBlockSetter(t1)
# Set up the PC.
- loadp CodeBlock::m_instructions[t1], t0
- loadp CodeBlock::Instructions::m_instructions + VectorBufferOffset[t0], PC
+ if JSVALUE64
+ loadp CodeBlock::m_instructions[t1], PB
+ move 0, PC
+ else
+ loadp CodeBlock::m_instructions[t1], PC
+ end
end
# Expects that CodeBlock is in t1, which is what prologue() leaves behind.
# Must call dispatch(0) after calling this.
macro functionInitialization(profileArgSkip)
- if JIT_ENABLED
+ if VALUE_PROFILER
# Profile the arguments. Unfortunately, we have no choice but to do this. This
# code is pretty horrendous because of the difference in ordering between
# arguments and value profiles, the desire to have a simple loop-down-to-zero
@@ -459,21 +243,27 @@ macro functionInitialization(profileArgSkip)
# optimal way for architectures that have more than five registers available
# for arbitrary use in the interpreter.
loadi CodeBlock::m_numParameters[t1], t0
- addi -profileArgSkip, t0 # Use addi because that's what has the peephole
- assert(macro (ok) bigteq t0, 0, ok end)
- btiz t0, .argumentProfileDone
+ addp -profileArgSkip, t0 # Use addi because that's what has the peephole
+ assert(macro (ok) bpgteq t0, 0, ok end)
+ btpz t0, .argumentProfileDone
loadp CodeBlock::m_argumentValueProfiles + VectorBufferOffset[t1], t3
- muli sizeof ValueProfile, t0, t2 # Aaaaahhhh! Need strength reduction!
- negi t0
- lshifti 3, t0
+ mulp sizeof ValueProfile, t0, t2 # Aaaaahhhh! Need strength reduction!
+ negp t0
+ lshiftp 3, t0
addp t2, t3
.argumentProfileLoop:
- loadi ThisArgumentOffset + TagOffset + 8 - profileArgSkip * 8[cfr, t0], t2
- subp sizeof ValueProfile, t3
- storei t2, profileArgSkip * sizeof ValueProfile + ValueProfile::m_buckets + TagOffset[t3]
- loadi ThisArgumentOffset + PayloadOffset + 8 - profileArgSkip * 8[cfr, t0], t2
- storei t2, profileArgSkip * sizeof ValueProfile + ValueProfile::m_buckets + PayloadOffset[t3]
- baddinz 8, t0, .argumentProfileLoop
+ if JSVALUE64
+ loadp ThisArgumentOffset + 8 - profileArgSkip * 8[cfr, t0], t2
+ subp sizeof ValueProfile, t3
+ storep t2, profileArgSkip * sizeof ValueProfile + ValueProfile::m_buckets[t3]
+ else
+ loadi ThisArgumentOffset + TagOffset + 8 - profileArgSkip * 8[cfr, t0], t2
+ subp sizeof ValueProfile, t3
+ storei t2, profileArgSkip * sizeof ValueProfile + ValueProfile::m_buckets + TagOffset[t3]
+ loadi ThisArgumentOffset + PayloadOffset + 8 - profileArgSkip * 8[cfr, t0], t2
+ storei t2, profileArgSkip * sizeof ValueProfile + ValueProfile::m_buckets + PayloadOffset[t3]
+ end
+ baddpnz 8, t0, .argumentProfileLoop
.argumentProfileDone:
end
@@ -490,101 +280,6 @@ macro functionInitialization(profileArgSkip)
.stackHeightOK:
end
-# Expects that CodeBlock is in t1, which is what prologue() leaves behind.
-macro functionArityCheck(doneLabel, slow_path)
- loadi PayloadOffset + ArgumentCount[cfr], t0
- biaeq t0, CodeBlock::m_numParameters[t1], doneLabel
- cCall2(slow_path, cfr, PC) # This slow_path has a simple protocol: t0 = 0 => no error, t0 != 0 => error
- move t1, cfr
- btiz t0, .continue
- loadp JITStackFrame::globalData[sp], t1
- loadp JSGlobalData::callFrameForThrow[t1], t0
- jmp JSGlobalData::targetMachinePCForThrow[t1]
-.continue:
- # Reload CodeBlock and PC, since the slow_path clobbered it.
- loadp CodeBlock[cfr], t1
- loadp CodeBlock::m_instructions[t1], t0
- loadp CodeBlock::Instructions::m_instructions + VectorBufferOffset[t0], PC
- jmp doneLabel
-end
-
-_llint_program_prologue:
- prologue(notFunctionCodeBlockGetter, notFunctionCodeBlockSetter, _llint_entry_osr, _llint_trace_prologue)
- dispatch(0)
-
-
-_llint_eval_prologue:
- prologue(notFunctionCodeBlockGetter, notFunctionCodeBlockSetter, _llint_entry_osr, _llint_trace_prologue)
- dispatch(0)
-
-
-_llint_function_for_call_prologue:
- prologue(functionForCallCodeBlockGetter, functionCodeBlockSetter, _llint_entry_osr_function_for_call, _llint_trace_prologue_function_for_call)
-.functionForCallBegin:
- functionInitialization(0)
- dispatch(0)
-
-
-_llint_function_for_construct_prologue:
- prologue(functionForConstructCodeBlockGetter, functionCodeBlockSetter, _llint_entry_osr_function_for_construct, _llint_trace_prologue_function_for_construct)
-.functionForConstructBegin:
- functionInitialization(1)
- dispatch(0)
-
-
-_llint_function_for_call_arity_check:
- prologue(functionForCallCodeBlockGetter, functionCodeBlockSetter, _llint_entry_osr_function_for_call_arityCheck, _llint_trace_arityCheck_for_call)
- functionArityCheck(.functionForCallBegin, _llint_slow_path_call_arityCheck)
-
-
-_llint_function_for_construct_arity_check:
- prologue(functionForConstructCodeBlockGetter, functionCodeBlockSetter, _llint_entry_osr_function_for_construct_arityCheck, _llint_trace_arityCheck_for_construct)
- functionArityCheck(.functionForConstructBegin, _llint_slow_path_construct_arityCheck)
-
-# Instruction implementations
-
-_llint_op_enter:
- traceExecution()
- loadp CodeBlock[cfr], t2
- loadi CodeBlock::m_numVars[t2], t2
- btiz t2, .opEnterDone
- move UndefinedTag, t0
- move 0, t1
-.opEnterLoop:
- subi 1, t2
- storei t0, TagOffset[cfr, t2, 8]
- storei t1, PayloadOffset[cfr, t2, 8]
- btinz t2, .opEnterLoop
-.opEnterDone:
- dispatch(1)
-
-
-_llint_op_create_activation:
- 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)
-
-
-_llint_op_create_arguments:
- traceExecution()
- loadi 4[PC], t0
- bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opCreateArgumentsDone
- callSlowPath(_llint_slow_path_create_arguments)
-.opCreateArgumentsDone:
- dispatch(2)
-
-
macro allocateBasicJSObject(sizeClassIndex, classInfoOffset, structure, result, scratch1, scratch2, slowCase)
if ALWAYS_ALLOCATE_SLOW
jmp slowCase
@@ -618,66 +313,62 @@ macro allocateBasicJSObject(sizeClassIndex, classInfoOffset, structure, result,
end
end
-_llint_op_create_this:
- traceExecution()
- loadi 8[PC], t0
- assertNotConstant(t0)
- bineq TagOffset[cfr, t0, 8], CellTag, .opCreateThisSlow
- loadi PayloadOffset[cfr, t0, 8], t0
- loadp JSCell::m_structure[t0], t1
- bbb Structure::m_typeInfo + TypeInfo::m_type[t1], ObjectType, .opCreateThisSlow
- loadp JSObject::m_inheritorID[t0], t2
- btpz t2, .opCreateThisSlow
- allocateBasicJSObject(JSFinalObjectSizeClassIndex, JSGlobalData::jsFinalObjectClassInfo, t2, t0, t1, t3, .opCreateThisSlow)
- loadi 4[PC], t1
- storei CellTag, TagOffset[cfr, t1, 8]
- storei t0, PayloadOffset[cfr, t1, 8]
- dispatch(3)
+macro doReturn()
+ loadp ReturnPC[cfr], t2
+ loadp CallerFrame[cfr], cfr
+ restoreReturnAddressBeforeReturn(t2)
+ ret
+end
-.opCreateThisSlow:
- callSlowPath(_llint_slow_path_create_this)
- dispatch(3)
+# Indicate the beginning of LLInt.
+_llint_begin:
+ crash()
-_llint_op_get_callee:
- traceExecution()
- loadi 4[PC], t0
- loadp PayloadOffset + Callee[cfr], t1
- storei CellTag, TagOffset[cfr, t0, 8]
- storei t1, PayloadOffset[cfr, t0, 8]
- dispatch(2)
+_llint_program_prologue:
+ prologue(notFunctionCodeBlockGetter, notFunctionCodeBlockSetter, _llint_entry_osr, _llint_trace_prologue)
+ dispatch(0)
-_llint_op_convert_this:
- traceExecution()
- loadi 4[PC], t0
- bineq TagOffset[cfr, t0, 8], CellTag, .opConvertThisSlow
- loadi PayloadOffset[cfr, t0, 8], t0
- loadp JSCell::m_structure[t0], t0
- bbb Structure::m_typeInfo + TypeInfo::m_type[t0], ObjectType, .opConvertThisSlow
- dispatch(2)
-.opConvertThisSlow:
- callSlowPath(_llint_slow_path_convert_this)
- dispatch(2)
+_llint_eval_prologue:
+ prologue(notFunctionCodeBlockGetter, notFunctionCodeBlockSetter, _llint_entry_osr, _llint_trace_prologue)
+ dispatch(0)
-_llint_op_new_object:
- traceExecution()
- loadp CodeBlock[cfr], t0
- loadp CodeBlock::m_globalObject[t0], t0
- loadp JSGlobalObject::m_emptyObjectStructure[t0], t1
- allocateBasicJSObject(JSFinalObjectSizeClassIndex, JSGlobalData::jsFinalObjectClassInfo, t1, t0, t2, t3, .opNewObjectSlow)
- loadi 4[PC], t1
- storei CellTag, TagOffset[cfr, t1, 8]
- storei t0, PayloadOffset[cfr, t1, 8]
- dispatch(2)
+_llint_function_for_call_prologue:
+ prologue(functionForCallCodeBlockGetter, functionCodeBlockSetter, _llint_entry_osr_function_for_call, _llint_trace_prologue_function_for_call)
+.functionForCallBegin:
+ functionInitialization(0)
+ dispatch(0)
+
-.opNewObjectSlow:
- callSlowPath(_llint_slow_path_new_object)
- dispatch(2)
+_llint_function_for_construct_prologue:
+ prologue(functionForConstructCodeBlockGetter, functionCodeBlockSetter, _llint_entry_osr_function_for_construct, _llint_trace_prologue_function_for_construct)
+.functionForConstructBegin:
+ functionInitialization(1)
+ dispatch(0)
+
+
+_llint_function_for_call_arity_check:
+ prologue(functionForCallCodeBlockGetter, functionCodeBlockSetter, _llint_entry_osr_function_for_call_arityCheck, _llint_trace_arityCheck_for_call)
+ functionArityCheck(.functionForCallBegin, _llint_slow_path_call_arityCheck)
+
+
+_llint_function_for_construct_arity_check:
+ prologue(functionForConstructCodeBlockGetter, functionCodeBlockSetter, _llint_entry_osr_function_for_construct_arityCheck, _llint_trace_arityCheck_for_construct)
+ functionArityCheck(.functionForConstructBegin, _llint_slow_path_construct_arityCheck)
+
+
+# Value-representation-specific code.
+if JSVALUE64
+ include LowLevelInterpreter64
+else
+ include LowLevelInterpreter32_64
+end
+# Value-representation-agnostic code.
_llint_op_new_array:
traceExecution()
callSlowPath(_llint_slow_path_new_array)
@@ -696,148 +387,6 @@ _llint_op_new_regexp:
dispatch(3)
-_llint_op_mov:
- 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)
-
-
-_llint_op_not:
- traceExecution()
- loadi 8[PC], t0
- loadi 4[PC], t1
- loadConstantOrVariable(t0, t2, t3)
- bineq t2, BooleanTag, .opNotSlow
- xori 1, t3
- storei t2, TagOffset[cfr, t1, 8]
- storei t3, PayloadOffset[cfr, t1, 8]
- dispatch(3)
-
-.opNotSlow:
- callSlowPath(_llint_slow_path_not)
- dispatch(3)
-
-
-_llint_op_eq:
- traceExecution()
- loadi 12[PC], t2
- loadi 8[PC], t0
- loadConstantOrVariable(t2, t3, t1)
- loadConstantOrVariable2Reg(t0, t2, t0)
- bineq t2, t3, .opEqSlow
- bieq t2, CellTag, .opEqSlow
- bib t2, LowestTag, .opEqSlow
- loadi 4[PC], t2
- cieq t0, t1, t0
- storei BooleanTag, TagOffset[cfr, t2, 8]
- storei t0, PayloadOffset[cfr, t2, 8]
- dispatch(4)
-
-.opEqSlow:
- callSlowPath(_llint_slow_path_eq)
- dispatch(4)
-
-
-_llint_op_eq_null:
- traceExecution()
- loadi 8[PC], t0
- loadi 4[PC], t3
- assertNotConstant(t0)
- loadi TagOffset[cfr, t0, 8], t1
- loadi PayloadOffset[cfr, t0, 8], t0
- bineq t1, CellTag, .opEqNullImmediate
- loadp JSCell::m_structure[t0], t1
- tbnz Structure::m_typeInfo + TypeInfo::m_flags[t1], MasqueradesAsUndefined, t1
- jmp .opEqNullNotImmediate
-.opEqNullImmediate:
- cieq t1, NullTag, t2
- cieq t1, UndefinedTag, t1
- ori t2, t1
-.opEqNullNotImmediate:
- storei BooleanTag, TagOffset[cfr, t3, 8]
- storei t1, PayloadOffset[cfr, t3, 8]
- dispatch(3)
-
-
-_llint_op_neq:
- traceExecution()
- loadi 12[PC], t2
- loadi 8[PC], t0
- loadConstantOrVariable(t2, t3, t1)
- loadConstantOrVariable2Reg(t0, t2, t0)
- bineq t2, t3, .opNeqSlow
- bieq t2, CellTag, .opNeqSlow
- bib t2, LowestTag, .opNeqSlow
- loadi 4[PC], t2
- cineq t0, t1, t0
- storei BooleanTag, TagOffset[cfr, t2, 8]
- storei t0, PayloadOffset[cfr, t2, 8]
- dispatch(4)
-
-.opNeqSlow:
- callSlowPath(_llint_slow_path_neq)
- dispatch(4)
-
-
-_llint_op_neq_null:
- traceExecution()
- loadi 8[PC], t0
- loadi 4[PC], t3
- assertNotConstant(t0)
- loadi TagOffset[cfr, t0, 8], t1
- loadi PayloadOffset[cfr, t0, 8], t0
- bineq t1, CellTag, .opNeqNullImmediate
- loadp JSCell::m_structure[t0], t1
- tbz Structure::m_typeInfo + TypeInfo::m_flags[t1], MasqueradesAsUndefined, t1
- jmp .opNeqNullNotImmediate
-.opNeqNullImmediate:
- cineq t1, NullTag, t2
- cineq t1, UndefinedTag, t1
- andi t2, t1
-.opNeqNullNotImmediate:
- storei BooleanTag, TagOffset[cfr, t3, 8]
- storei t1, PayloadOffset[cfr, t3, 8]
- dispatch(3)
-
-
-macro strictEq(equalityOperation, slow_path)
- loadi 12[PC], t2
- loadi 8[PC], t0
- loadConstantOrVariable(t2, t3, t1)
- loadConstantOrVariable2Reg(t0, t2, t0)
- bineq t2, t3, .slow
- bib t2, LowestTag, .slow
- bineq t2, CellTag, .notString
- loadp JSCell::m_structure[t0], t2
- loadp JSCell::m_structure[t1], t3
- bbneq Structure::m_typeInfo + TypeInfo::m_type[t2], StringType, .notString
- bbeq Structure::m_typeInfo + TypeInfo::m_type[t3], StringType, .slow
-.notString:
- loadi 4[PC], t2
- equalityOperation(t0, t1, t0)
- storei BooleanTag, TagOffset[cfr, t2, 8]
- storei t0, PayloadOffset[cfr, t2, 8]
- dispatch(4)
-
-.slow:
- callSlowPath(slow_path)
- dispatch(4)
-end
-
-_llint_op_stricteq:
- traceExecution()
- strictEq(macro (left, right, result) cieq left, right, result end, _llint_slow_path_stricteq)
-
-
-_llint_op_nstricteq:
- traceExecution()
- strictEq(macro (left, right, result) cineq left, right, result end, _llint_slow_path_nstricteq)
-
-
_llint_op_less:
traceExecution()
callSlowPath(_llint_slow_path_less)
@@ -862,360 +411,12 @@ _llint_op_greatereq:
dispatch(4)
-_llint_op_pre_inc:
- traceExecution()
- loadi 4[PC], t0
- bineq TagOffset[cfr, t0, 8], Int32Tag, .opPreIncSlow
- loadi PayloadOffset[cfr, t0, 8], t1
- baddio 1, t1, .opPreIncSlow
- storei t1, PayloadOffset[cfr, t0, 8]
- dispatch(2)
-
-.opPreIncSlow:
- callSlowPath(_llint_slow_path_pre_inc)
- dispatch(2)
-
-
-_llint_op_pre_dec:
- traceExecution()
- loadi 4[PC], t0
- bineq TagOffset[cfr, t0, 8], Int32Tag, .opPreDecSlow
- loadi PayloadOffset[cfr, t0, 8], t1
- bsubio 1, t1, .opPreDecSlow
- storei t1, PayloadOffset[cfr, t0, 8]
- dispatch(2)
-
-.opPreDecSlow:
- callSlowPath(_llint_slow_path_pre_dec)
- dispatch(2)
-
-
-_llint_op_post_inc:
- traceExecution()
- loadi 8[PC], t0
- loadi 4[PC], t1
- bineq TagOffset[cfr, t0, 8], Int32Tag, .opPostIncSlow
- bieq t0, t1, .opPostIncDone
- loadi PayloadOffset[cfr, t0, 8], t2
- move t2, t3
- baddio 1, t3, .opPostIncSlow
- storei Int32Tag, TagOffset[cfr, t1, 8]
- storei t2, PayloadOffset[cfr, t1, 8]
- storei t3, PayloadOffset[cfr, t0, 8]
-.opPostIncDone:
- dispatch(3)
-
-.opPostIncSlow:
- callSlowPath(_llint_slow_path_post_inc)
- dispatch(3)
-
-
-_llint_op_post_dec:
- traceExecution()
- loadi 8[PC], t0
- loadi 4[PC], t1
- bineq TagOffset[cfr, t0, 8], Int32Tag, .opPostDecSlow
- bieq t0, t1, .opPostDecDone
- loadi PayloadOffset[cfr, t0, 8], t2
- move t2, t3
- bsubio 1, t3, .opPostDecSlow
- storei Int32Tag, TagOffset[cfr, t1, 8]
- storei t2, PayloadOffset[cfr, t1, 8]
- storei t3, PayloadOffset[cfr, t0, 8]
-.opPostDecDone:
- dispatch(3)
-
-.opPostDecSlow:
- callSlowPath(_llint_slow_path_post_dec)
- dispatch(3)
-
-
-_llint_op_to_jsnumber:
- traceExecution()
- loadi 8[PC], t0
- loadi 4[PC], t1
- loadConstantOrVariable(t0, t2, t3)
- bieq t2, Int32Tag, .opToJsnumberIsInt
- biaeq t2, EmptyValueTag, .opToJsnumberSlow
-.opToJsnumberIsInt:
- storei t2, TagOffset[cfr, t1, 8]
- storei t3, PayloadOffset[cfr, t1, 8]
- dispatch(3)
-
-.opToJsnumberSlow:
- callSlowPath(_llint_slow_path_to_jsnumber)
- dispatch(3)
-
-
-_llint_op_negate:
- traceExecution()
- loadi 8[PC], t0
- loadi 4[PC], t3
- loadConstantOrVariable(t0, t1, t2)
- bineq t1, Int32Tag, .opNegateSrcNotInt
- btiz t2, 0x7fffffff, .opNegateSlow
- negi t2
- storei Int32Tag, TagOffset[cfr, t3, 8]
- storei t2, PayloadOffset[cfr, t3, 8]
- dispatch(3)
-.opNegateSrcNotInt:
- bia t1, LowestTag, .opNegateSlow
- xori 0x80000000, t1
- storei t1, TagOffset[cfr, t3, 8]
- storei t2, PayloadOffset[cfr, t3, 8]
- dispatch(3)
-
-.opNegateSlow:
- callSlowPath(_llint_slow_path_negate)
- dispatch(3)
-
-
-macro binaryOpCustomStore(integerOperationAndStore, doubleOperation, slow_path)
- loadi 12[PC], t2
- loadi 8[PC], t0
- loadConstantOrVariable(t2, t3, t1)
- loadConstantOrVariable2Reg(t0, t2, t0)
- bineq t2, Int32Tag, .op1NotInt
- bineq t3, Int32Tag, .op2NotInt
- loadi 4[PC], t2
- integerOperationAndStore(t3, t1, t0, .slow, t2)
- dispatch(5)
-
-.op1NotInt:
- # First operand is definitely not an int, the second operand could be anything.
- bia t2, LowestTag, .slow
- bib t3, LowestTag, .op1NotIntOp2Double
- bineq t3, Int32Tag, .slow
- ci2d t1, ft1
- jmp .op1NotIntReady
-.op1NotIntOp2Double:
- fii2d t1, t3, ft1
-.op1NotIntReady:
- loadi 4[PC], t1
- fii2d t0, t2, ft0
- doubleOperation(ft1, ft0)
- stored ft0, [cfr, t1, 8]
- dispatch(5)
-
-.op2NotInt:
- # First operand is definitely an int, the second operand is definitely not.
- loadi 4[PC], t2
- bia t3, LowestTag, .slow
- ci2d t0, ft0
- fii2d t1, t3, ft1
- doubleOperation(ft1, ft0)
- stored ft0, [cfr, t2, 8]
- dispatch(5)
-
-.slow:
- callSlowPath(slow_path)
- dispatch(5)
-end
-
-macro binaryOp(integerOperation, doubleOperation, slow_path)
- binaryOpCustomStore(
- macro (int32Tag, left, right, slow, index)
- integerOperation(left, right, slow)
- storei int32Tag, TagOffset[cfr, index, 8]
- storei right, PayloadOffset[cfr, index, 8]
- end,
- doubleOperation, slow_path)
-end
-
-_llint_op_add:
- traceExecution()
- binaryOp(
- macro (left, right, slow) baddio left, right, slow end,
- macro (left, right) addd left, right end,
- _llint_slow_path_add)
-
-
-_llint_op_mul:
- traceExecution()
- binaryOpCustomStore(
- macro (int32Tag, left, right, slow, index)
- const scratch = int32Tag # We know that we can reuse the int32Tag register since it has a constant.
- move right, scratch
- bmulio left, scratch, slow
- btinz scratch, .done
- bilt left, 0, slow
- bilt right, 0, slow
- .done:
- storei Int32Tag, TagOffset[cfr, index, 8]
- storei scratch, PayloadOffset[cfr, index, 8]
- end,
- macro (left, right) muld left, right end,
- _llint_slow_path_mul)
-
-
-_llint_op_sub:
- traceExecution()
- binaryOp(
- macro (left, right, slow) bsubio left, right, slow end,
- macro (left, right) subd left, right end,
- _llint_slow_path_sub)
-
-
-_llint_op_div:
- traceExecution()
- binaryOpCustomStore(
- macro (int32Tag, left, right, slow, index)
- ci2d left, ft0
- ci2d right, ft1
- divd ft0, ft1
- bcd2i ft1, right, .notInt
- storei int32Tag, TagOffset[cfr, index, 8]
- storei right, PayloadOffset[cfr, index, 8]
- jmp .done
- .notInt:
- stored ft1, [cfr, index, 8]
- .done:
- end,
- macro (left, right) divd left, right end,
- _llint_slow_path_div)
-
-
_llint_op_mod:
traceExecution()
callSlowPath(_llint_slow_path_mod)
dispatch(4)
-macro bitOp(operation, slow_path, advance)
- loadi 12[PC], t2
- loadi 8[PC], t0
- loadConstantOrVariable(t2, t3, t1)
- loadConstantOrVariable2Reg(t0, t2, t0)
- bineq t3, Int32Tag, .slow
- bineq t2, Int32Tag, .slow
- loadi 4[PC], t2
- operation(t1, t0, .slow)
- storei t3, TagOffset[cfr, t2, 8]
- storei t0, PayloadOffset[cfr, t2, 8]
- dispatch(advance)
-
-.slow:
- callSlowPath(slow_path)
- dispatch(advance)
-end
-
-_llint_op_lshift:
- traceExecution()
- bitOp(
- macro (left, right, slow) lshifti left, right end,
- _llint_slow_path_lshift,
- 4)
-
-
-_llint_op_rshift:
- traceExecution()
- bitOp(
- macro (left, right, slow) rshifti left, right end,
- _llint_slow_path_rshift,
- 4)
-
-
-_llint_op_urshift:
- traceExecution()
- bitOp(
- macro (left, right, slow)
- urshifti left, right
- bilt right, 0, slow
- end,
- _llint_slow_path_urshift,
- 4)
-
-
-_llint_op_bitand:
- traceExecution()
- bitOp(
- macro (left, right, slow) andi left, right end,
- _llint_slow_path_bitand,
- 5)
-
-
-_llint_op_bitxor:
- traceExecution()
- bitOp(
- macro (left, right, slow) xori left, right end,
- _llint_slow_path_bitxor,
- 5)
-
-
-_llint_op_bitor:
- traceExecution()
- bitOp(
- macro (left, right, slow) ori left, right end,
- _llint_slow_path_bitor,
- 5)
-
-
-_llint_op_bitnot:
- traceExecution()
- loadi 8[PC], t1
- loadi 4[PC], t0
- loadConstantOrVariable(t1, t2, t3)
- bineq t2, Int32Tag, .opBitnotSlow
- noti t3
- storei t2, TagOffset[cfr, t0, 8]
- storei t3, PayloadOffset[cfr, t0, 8]
- dispatch(3)
-
-.opBitnotSlow:
- callSlowPath(_llint_slow_path_bitnot)
- dispatch(3)
-
-
-_llint_op_check_has_instance:
- traceExecution()
- loadi 4[PC], t1
- loadConstantOrVariablePayload(t1, CellTag, t0, .opCheckHasInstanceSlow)
- loadp JSCell::m_structure[t0], t0
- btbz Structure::m_typeInfo + TypeInfo::m_flags[t0], ImplementsHasInstance, .opCheckHasInstanceSlow
- dispatch(2)
-
-.opCheckHasInstanceSlow:
- callSlowPath(_llint_slow_path_check_has_instance)
- dispatch(2)
-
-
-_llint_op_instanceof:
- traceExecution()
- # Check that baseVal implements the default HasInstance behavior.
- # FIXME: This should be deprecated.
- loadi 12[PC], t1
- loadConstantOrVariablePayloadUnchecked(t1, t0)
- loadp JSCell::m_structure[t0], t0
- btbz Structure::m_typeInfo + TypeInfo::m_flags[t0], ImplementsDefaultHasInstance, .opInstanceofSlow
-
- # Actually do the work.
- loadi 16[PC], t0
- loadi 4[PC], t3
- loadConstantOrVariablePayload(t0, CellTag, t1, .opInstanceofSlow)
- loadp JSCell::m_structure[t1], t2
- bbb Structure::m_typeInfo + TypeInfo::m_type[t2], ObjectType, .opInstanceofSlow
- loadi 8[PC], t0
- loadConstantOrVariablePayload(t0, CellTag, t2, .opInstanceofSlow)
-
- # Register state: t1 = prototype, t2 = value
- move 1, t0
-.opInstanceofLoop:
- loadp JSCell::m_structure[t2], t2
- loadi Structure::m_prototype + PayloadOffset[t2], t2
- bpeq t2, t1, .opInstanceofDone
- btinz t2, .opInstanceofLoop
-
- move 0, t0
-.opInstanceofDone:
- storei BooleanTag, TagOffset[cfr, t3, 8]
- storei t0, PayloadOffset[cfr, t3, 8]
- dispatch(5)
-
-.opInstanceofSlow:
- callSlowPath(_llint_slow_path_instanceof)
- dispatch(5)
-
-
_llint_op_typeof:
traceExecution()
callSlowPath(_llint_slow_path_typeof)
@@ -1276,156 +477,6 @@ _llint_op_resolve_skip:
dispatch(5)
-macro resolveGlobal(size, slow)
- # Operands are as follows:
- # 4[PC] Destination for the load.
- # 8[PC] Property identifier index in the code block.
- # 12[PC] Structure pointer, initialized to 0 by bytecode generator.
- # 16[PC] Offset in global object, initialized to 0 by bytecode generator.
- loadp CodeBlock[cfr], t0
- loadp CodeBlock::m_globalObject[t0], t0
- loadp JSCell::m_structure[t0], t1
- bpneq t1, 12[PC], slow
- loadi 16[PC], t1
- loadp JSObject::m_propertyStorage[t0], t0
- loadi TagOffset[t0, t1, 8], t2
- loadi PayloadOffset[t0, t1, 8], t3
- loadi 4[PC], t0
- storei t2, TagOffset[cfr, t0, 8]
- storei t3, PayloadOffset[cfr, t0, 8]
- loadi (size - 1) * 4[PC], t0
- valueProfile(t2, t3, t0)
-end
-
-_llint_op_resolve_global:
- traceExecution()
- resolveGlobal(6, .opResolveGlobalSlow)
- dispatch(6)
-
-.opResolveGlobalSlow:
- callSlowPath(_llint_slow_path_resolve_global)
- dispatch(6)
-
-
-# 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 getScope(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_needsFullScopeChain[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 ScopeChainNode::next[t0], t0
-.noActivation:
- subi 1, t2
-
- btiz t2, .done
-.loop:
- scopeCheck(t0, t1)
- loadp ScopeChainNode::next[t0], t0
- subi 1, t2
- btinz t2, .loop
-
-.done:
-end
-
-_llint_op_resolve_global_dynamic:
- traceExecution()
- loadp JITStackFrame::globalData[sp], t3
- loadp JSGlobalData::activationStructure[t3], t3
- getScope(
- 20[PC],
- macro (scope, scratch)
- loadp ScopeChainNode::object[scope], scratch
- bpneq JSCell::m_structure[scratch], t3, .opResolveGlobalDynamicSuperSlow
- end)
- resolveGlobal(7, .opResolveGlobalDynamicSlow)
- dispatch(7)
-
-.opResolveGlobalDynamicSuperSlow:
- callSlowPath(_llint_slow_path_resolve_for_resolve_global_dynamic)
- dispatch(7)
-
-.opResolveGlobalDynamicSlow:
- callSlowPath(_llint_slow_path_resolve_global_dynamic)
- dispatch(7)
-
-
-_llint_op_get_scoped_var:
- traceExecution()
- # Operands are as follows:
- # 4[PC] Destination for the load.
- # 8[PC] Index of register in the scope.
- # 12[PC] De Bruijin index.
- getScope(12[PC], macro (scope, scratch) end)
- loadi 4[PC], t1
- loadi 8[PC], t2
- loadp ScopeChainNode::object[t0], t0
- loadp JSVariableObject::m_registers[t0], t0
- loadi TagOffset[t0, t2, 8], t3
- loadi PayloadOffset[t0, t2, 8], t0
- storei t3, TagOffset[cfr, t1, 8]
- storei t0, PayloadOffset[cfr, t1, 8]
- loadi 16[PC], t1
- valueProfile(t3, t0, t1)
- dispatch(5)
-
-
-_llint_op_put_scoped_var:
- traceExecution()
- getScope(8[PC], macro (scope, scratch) end)
- loadi 12[PC], t1
- loadConstantOrVariable(t1, t3, t2)
- loadi 4[PC], t1
- writeBarrier(t3, t2)
- loadp ScopeChainNode::object[t0], t0
- loadp JSVariableObject::m_registers[t0], t0
- storei t3, TagOffset[t0, t1, 8]
- storei t2, PayloadOffset[t0, t1, 8]
- dispatch(4)
-
-
-_llint_op_get_global_var:
- traceExecution()
- loadi 8[PC], t1
- loadi 4[PC], t3
- loadp CodeBlock[cfr], t0
- loadp CodeBlock::m_globalObject[t0], t0
- loadp JSGlobalObject::m_registers[t0], t0
- loadi TagOffset[t0, t1, 8], t2
- loadi PayloadOffset[t0, t1, 8], t1
- storei t2, TagOffset[cfr, t3, 8]
- storei t1, PayloadOffset[cfr, t3, 8]
- loadi 12[PC], t3
- valueProfile(t2, t1, t3)
- dispatch(4)
-
-
-_llint_op_put_global_var:
- traceExecution()
- loadi 8[PC], t1
- loadp CodeBlock[cfr], t0
- loadp CodeBlock::m_globalObject[t0], t0
- loadp JSGlobalObject::m_registers[t0], t0
- loadConstantOrVariable(t1, t2, t3)
- loadi 4[PC], t1
- writeBarrier(t2, t3)
- storei t2, TagOffset[t0, t1, 8]
- storei t3, PayloadOffset[t0, t1, 8]
- dispatch(3)
-
-
_llint_op_resolve_base:
traceExecution()
callSlowPath(_llint_slow_path_resolve_base)
@@ -1450,230 +501,12 @@ _llint_op_resolve_with_this:
dispatch(5)
-_llint_op_get_by_id:
- traceExecution()
- # We only do monomorphic get_by_id caching for now, and we do not modify the
- # opcode. We do, however, allow for the cache to change anytime if fails, since
- # ping-ponging is free. At best we get lucky and the get_by_id will continue
- # to take fast path on the new cache. At worst we take slow path, which is what
- # we would have been doing anyway.
- loadi 8[PC], t0
- loadi 16[PC], t1
- loadConstantOrVariablePayload(t0, CellTag, t3, .opGetByIdSlow)
- loadi 20[PC], t2
- loadp JSObject::m_propertyStorage[t3], t0
- bpneq JSCell::m_structure[t3], t1, .opGetByIdSlow
- loadi 4[PC], t1
- loadi TagOffset[t0, t2], t3
- loadi PayloadOffset[t0, t2], t2
- storei t3, TagOffset[cfr, t1, 8]
- storei t2, PayloadOffset[cfr, t1, 8]
- loadi 32[PC], t1
- valueProfile(t3, t2, t1)
- dispatch(9)
-
-.opGetByIdSlow:
- callSlowPath(_llint_slow_path_get_by_id)
- 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)
-
-
-_llint_op_put_by_id:
- traceExecution()
- loadi 4[PC], t3
- loadi 16[PC], t1
- loadConstantOrVariablePayload(t3, CellTag, t0, .opPutByIdSlow)
- loadi 12[PC], t2
- loadp JSObject::m_propertyStorage[t0], t3
- bpneq JSCell::m_structure[t0], t1, .opPutByIdSlow
- loadi 20[PC], t1
- loadConstantOrVariable2Reg(t2, t0, t2)
- writeBarrier(t0, t2)
- storei t0, TagOffset[t3, t1]
- storei t2, PayloadOffset[t3, t1]
- dispatch(9)
-
-.opPutByIdSlow:
- callSlowPath(_llint_slow_path_put_by_id)
- dispatch(9)
-
-
-macro putByIdTransition(additionalChecks)
- traceExecution()
- loadi 4[PC], t3
- loadi 16[PC], t1
- loadConstantOrVariablePayload(t3, CellTag, t0, .opPutByIdSlow)
- loadi 12[PC], t2
- bpneq JSCell::m_structure[t0], t1, .opPutByIdSlow
- additionalChecks(t1, t3, .opPutByIdSlow)
- loadi 20[PC], t1
- loadp JSObject::m_propertyStorage[t0], t3
- addp t1, t3
- loadConstantOrVariable2Reg(t2, t1, t2)
- writeBarrier(t1, t2)
- storei t1, TagOffset[t3]
- loadi 24[PC], t1
- storei t2, PayloadOffset[t3]
- storep t1, JSCell::m_structure[t0]
- dispatch(9)
-end
-
-_llint_op_put_by_id_transition_direct:
- putByIdTransition(macro (oldStructure, scratch, slow) end)
-
-
-_llint_op_put_by_id_transition_normal:
- putByIdTransition(
- macro (oldStructure, scratch, slow)
- const protoCell = oldStructure # Reusing the oldStructure register for the proto
-
- loadp 28[PC], scratch
- assert(macro (ok) btpnz scratch, ok end)
- loadp StructureChain::m_vector[scratch], scratch
- assert(macro (ok) btpnz scratch, ok end)
- bieq Structure::m_prototype + TagOffset[oldStructure], NullTag, .done
- .loop:
- loadi Structure::m_prototype + PayloadOffset[oldStructure], protoCell
- loadp JSCell::m_structure[protoCell], oldStructure
- bpneq oldStructure, [scratch], slow
- addp 4, scratch
- bineq Structure::m_prototype + TagOffset[oldStructure], NullTag, .loop
- .done:
- end)
-
-
_llint_op_del_by_id:
traceExecution()
callSlowPath(_llint_slow_path_del_by_id)
dispatch(4)
-_llint_op_get_by_val:
- traceExecution()
- loadp CodeBlock[cfr], t1
- loadi 8[PC], t2
- loadi 12[PC], t3
- loadp CodeBlock::m_globalData[t1], t1
- loadConstantOrVariablePayload(t2, CellTag, t0, .opGetByValSlow)
- loadp JSGlobalData::jsArrayClassInfo[t1], t2
- loadConstantOrVariablePayload(t3, Int32Tag, t1, .opGetByValSlow)
- bpneq [t0], t2, .opGetByValSlow
- loadp JSArray::m_storage[t0], t3
- biaeq t1, JSArray::m_vectorLength[t0], .opGetByValSlow
- loadi 4[PC], t0
- loadi ArrayStorage::m_vector + TagOffset[t3, t1, 8], t2
- loadi ArrayStorage::m_vector + PayloadOffset[t3, t1, 8], t1
- bieq t2, EmptyValueTag, .opGetByValSlow
- storei t2, TagOffset[cfr, t0, 8]
- storei t1, PayloadOffset[cfr, t0, 8]
- loadi 16[PC], t0
- valueProfile(t2, t1, t0)
- dispatch(5)
-
-.opGetByValSlow:
- callSlowPath(_llint_slow_path_get_by_val)
- dispatch(5)
-
-
-_llint_op_get_argument_by_val:
- 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
- negi t2
- 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]
- dispatch(5)
-
-.opGetArgumentByValSlow:
- callSlowPath(_llint_slow_path_get_argument_by_val)
- dispatch(5)
-
-
-_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_structure[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
- loadp JSObject::m_propertyStorage[t2], t2
- loadi TagOffset[t2, t0, 8], t1
- loadi PayloadOffset[t2, t0, 8], 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)
-
-
-_llint_op_put_by_val:
- traceExecution()
- loadi 4[PC], t0
- loadConstantOrVariablePayload(t0, CellTag, t1, .opPutByValSlow)
- loadi 8[PC], t0
- loadConstantOrVariablePayload(t0, Int32Tag, t2, .opPutByValSlow)
- loadp CodeBlock[cfr], t0
- loadp CodeBlock::m_globalData[t0], t0
- loadp JSGlobalData::jsArrayClassInfo[t0], t0
- bpneq [t1], t0, .opPutByValSlow
- biaeq t2, JSArray::m_vectorLength[t1], .opPutByValSlow
- loadp JSArray::m_storage[t1], t0
- bieq ArrayStorage::m_vector + TagOffset[t0, t2, 8], EmptyValueTag, .opPutByValEmpty
-.opPutByValStoreResult:
- loadi 12[PC], t3
- loadConstantOrVariable2Reg(t3, t1, t3)
- writeBarrier(t1, t3)
- storei t1, ArrayStorage::m_vector + TagOffset[t0, t2, 8]
- storei t3, ArrayStorage::m_vector + PayloadOffset[t0, t2, 8]
- dispatch(4)
-
-.opPutByValEmpty:
- addi 1, ArrayStorage::m_numValuesInVector[t0]
- bib t2, ArrayStorage::m_length[t0], .opPutByValStoreResult
- addi 1, t2, t1
- storei t1, ArrayStorage::m_length[t0]
- jmp .opPutByValStoreResult
-
-.opPutByValSlow:
- callSlowPath(_llint_slow_path_put_by_val)
- dispatch(4)
-
-
_llint_op_del_by_val:
traceExecution()
callSlowPath(_llint_slow_path_del_by_val)
@@ -1692,33 +525,12 @@ _llint_op_put_getter_setter:
dispatch(5)
-_llint_op_loop:
- nop
-_llint_op_jmp:
- traceExecution()
- dispatchBranch(4[PC])
-
-
_llint_op_jmp_scopes:
traceExecution()
callSlowPath(_llint_slow_path_jmp_scopes)
dispatch(0)
-macro jumpTrueOrFalse(conditionOp, slow)
- loadi 4[PC], t1
- loadConstantOrVariablePayload(t1, BooleanTag, t0, .slow)
- conditionOp(t0, .target)
- dispatch(3)
-
-.target:
- dispatchBranch(8[PC])
-
-.slow:
- callSlowPath(slow)
- dispatch(0)
-end
-
_llint_op_loop_if_true:
nop
_llint_op_jtrue:
@@ -1737,88 +549,6 @@ _llint_op_jfalse:
_llint_slow_path_jfalse)
-macro equalNull(cellHandler, immediateHandler)
- loadi 4[PC], t0
- loadi TagOffset[cfr, t0, 8], t1
- loadi PayloadOffset[cfr, t0, 8], t0
- bineq t1, CellTag, .immediate
- loadp JSCell::m_structure[t0], t2
- cellHandler(Structure::m_typeInfo + TypeInfo::m_flags[t2], .target)
- dispatch(3)
-
-.target:
- dispatchBranch(8[PC])
-
-.immediate:
- ori 1, t1
- immediateHandler(t1, .target)
- dispatch(3)
-end
-
-_llint_op_jeq_null:
- traceExecution()
- equalNull(
- macro (value, target) btbnz value, MasqueradesAsUndefined, target end,
- macro (value, target) bieq value, NullTag, target end)
-
-
-_llint_op_jneq_null:
- traceExecution()
- equalNull(
- macro (value, target) btbz value, MasqueradesAsUndefined, target end,
- macro (value, target) bineq value, NullTag, target end)
-
-
-_llint_op_jneq_ptr:
- traceExecution()
- loadi 4[PC], t0
- loadi 8[PC], t1
- bineq TagOffset[cfr, t0, 8], CellTag, .opJneqPtrBranch
- bpeq PayloadOffset[cfr, t0, 8], t1, .opJneqPtrFallThrough
-.opJneqPtrBranch:
- dispatchBranch(12[PC])
-.opJneqPtrFallThrough:
- dispatch(4)
-
-
-macro compare(integerCompare, doubleCompare, slow_path)
- loadi 4[PC], t2
- loadi 8[PC], t3
- loadConstantOrVariable(t2, t0, t1)
- loadConstantOrVariable2Reg(t3, t2, t3)
- bineq t0, Int32Tag, .op1NotInt
- bineq t2, Int32Tag, .op2NotInt
- integerCompare(t1, t3, .jumpTarget)
- dispatch(4)
-
-.op1NotInt:
- bia t0, LowestTag, .slow
- bib t2, LowestTag, .op1NotIntOp2Double
- bineq t2, Int32Tag, .slow
- ci2d t3, ft1
- jmp .op1NotIntReady
-.op1NotIntOp2Double:
- fii2d t3, t2, ft1
-.op1NotIntReady:
- fii2d t1, t0, ft0
- doubleCompare(ft0, ft1, .jumpTarget)
- dispatch(4)
-
-.op2NotInt:
- ci2d t1, ft0
- bia t2, LowestTag, .slow
- fii2d t3, t2, ft1
- doubleCompare(ft0, ft1, .jumpTarget)
- dispatch(4)
-
-.jumpTarget:
- dispatchBranch(12[PC])
-
-.slow:
- callSlowPath(slow_path)
- dispatch(0)
-end
-
_llint_op_loop_if_less:
nop
_llint_op_jless:
@@ -1897,117 +627,18 @@ _llint_op_loop_hint:
dispatch(1)
-_llint_op_switch_imm:
- traceExecution()
- loadi 12[PC], t2
- loadi 4[PC], t3
- loadConstantOrVariable(t2, t1, t0)
- loadp CodeBlock[cfr], t2
- loadp CodeBlock::m_rareData[t2], t2
- muli sizeof SimpleJumpTable, t3 # FIXME: would be nice to peephole this!
- loadp CodeBlock::RareData::m_immediateSwitchJumpTables + VectorBufferOffset[t2], t2
- addp t3, t2
- bineq t1, Int32Tag, .opSwitchImmNotInt
- subi SimpleJumpTable::min[t2], t0
- biaeq t0, SimpleJumpTable::branchOffsets + VectorSizeOffset[t2], .opSwitchImmFallThrough
- loadp SimpleJumpTable::branchOffsets + VectorBufferOffset[t2], t3
- loadi [t3, t0, 4], t1
- btiz t1, .opSwitchImmFallThrough
- dispatchBranchWithOffset(t1)
-
-.opSwitchImmNotInt:
- bib t1, LowestTag, .opSwitchImmSlow # Go to slow path if it's a double.
-.opSwitchImmFallThrough:
- dispatchBranch(8[PC])
-
-.opSwitchImmSlow:
- callSlowPath(_llint_slow_path_switch_imm)
- dispatch(0)
-
-
-_llint_op_switch_char:
- traceExecution()
- loadi 12[PC], t2
- loadi 4[PC], t3
- loadConstantOrVariable(t2, t1, t0)
- loadp CodeBlock[cfr], t2
- loadp CodeBlock::m_rareData[t2], t2
- muli sizeof SimpleJumpTable, t3
- loadp CodeBlock::RareData::m_characterSwitchJumpTables + VectorBufferOffset[t2], t2
- addp t3, t2
- bineq t1, CellTag, .opSwitchCharFallThrough
- loadp JSCell::m_structure[t0], t1
- bbneq Structure::m_typeInfo + TypeInfo::m_type[t1], StringType, .opSwitchCharFallThrough
- loadp JSString::m_value[t0], t0
- bineq StringImpl::m_length[t0], 1, .opSwitchCharFallThrough
- loadp StringImpl::m_data8[t0], t1
- btinz StringImpl::m_hashAndFlags[t0], HashFlags8BitBuffer, .opSwitchChar8Bit
- loadh [t1], t0
- jmp .opSwitchCharReady
-.opSwitchChar8Bit:
- loadb [t1], t0
-.opSwitchCharReady:
- subi SimpleJumpTable::min[t2], t0
- biaeq t0, SimpleJumpTable::branchOffsets + VectorSizeOffset[t2], .opSwitchCharFallThrough
- loadp SimpleJumpTable::branchOffsets + VectorBufferOffset[t2], t2
- loadi [t2, t0, 4], t1
- btiz t1, .opSwitchImmFallThrough
- dispatchBranchWithOffset(t1)
-
-.opSwitchCharFallThrough:
- dispatchBranch(8[PC])
-
-
_llint_op_switch_string:
traceExecution()
callSlowPath(_llint_slow_path_switch_string)
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_func_exp:
traceExecution()
callSlowPath(_llint_slow_path_new_func_exp)
dispatch(3)
-macro doCall(slow_path)
- loadi 4[PC], t0
- loadi 16[PC], t1
- loadp LLIntCallLinkInfo::callee[t1], t2
- loadConstantOrVariablePayload(t0, CellTag, t3, .opCallSlow)
- bineq t3, t2, .opCallSlow
- loadi 12[PC], t3
- addp 24, PC
- lshifti 3, t3
- addp cfr, t3 # t3 contains the new value of cfr
- loadp JSFunction::m_scopeChain[t2], t0
- storei t2, Callee + PayloadOffset[t3]
- storei t0, ScopeChain + PayloadOffset[t3]
- loadi 8 - 24[PC], t2
- storei PC, ArgumentCount + TagOffset[cfr]
- storep cfr, CallerFrame[t3]
- storei t2, ArgumentCount + PayloadOffset[t3]
- storei CellTag, Callee + TagOffset[t3]
- storei CellTag, ScopeChain + TagOffset[t3]
- move t3, cfr
- call LLIntCallLinkInfo::machineCodeTarget[t1]
- dispatchAfterCall()
-
-.opCallSlow:
- slowPathForCall(6, slow_path)
-end
-
_llint_op_call:
traceExecution()
doCall(_llint_slow_path_call)
@@ -2066,97 +697,16 @@ _llint_generic_return_point:
dispatchAfterCall()
-_llint_op_tear_off_activation:
- traceExecution()
- loadi 4[PC], t0
- loadi 8[PC], t1
- bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opTearOffActivationCreated
- bieq TagOffset[cfr, t1, 8], EmptyValueTag, .opTearOffActivationNotCreated
-.opTearOffActivationCreated:
- callSlowPath(_llint_slow_path_tear_off_activation)
-.opTearOffActivationNotCreated:
- dispatch(3)
-
-
-_llint_op_tear_off_arguments:
- traceExecution()
- loadi 4[PC], t0
- subi 1, t0 # Get the unmodifiedArgumentsRegister
- bieq TagOffset[cfr, t0, 8], EmptyValueTag, .opTearOffArgumentsNotCreated
- callSlowPath(_llint_slow_path_tear_off_arguments)
-.opTearOffArgumentsNotCreated:
- dispatch(2)
-
-
-macro doReturn()
- loadp ReturnPC[cfr], t2
- loadp CallerFrame[cfr], cfr
- restoreReturnAddressBeforeReturn(t2)
- ret
-end
-
-_llint_op_ret:
- traceExecution()
- checkSwitchToJITForEpilogue()
- loadi 4[PC], t2
- loadConstantOrVariable(t2, t1, t0)
- doReturn()
-
-
-_llint_op_call_put_result:
- loadi 4[PC], t2
- loadi 8[PC], t3
- storei t1, TagOffset[cfr, t2, 8]
- storei t0, PayloadOffset[cfr, t2, 8]
- valueProfile(t1, t0, t3)
- traceExecution() # Needs to be here because it would clobber t1, t0
- dispatch(3)
-
-
-_llint_op_ret_object_or_this:
- traceExecution()
- checkSwitchToJITForEpilogue()
- loadi 4[PC], t2
- loadConstantOrVariable(t2, t1, t0)
- bineq t1, CellTag, .opRetObjectOrThisNotObject
- loadp JSCell::m_structure[t0], t2
- bbb Structure::m_typeInfo + TypeInfo::m_type[t2], ObjectType, .opRetObjectOrThisNotObject
- doReturn()
-
-.opRetObjectOrThisNotObject:
- loadi 8[PC], t2
- loadConstantOrVariable(t2, t1, t0)
- doReturn()
-
-
-_llint_op_method_check:
- traceExecution()
- # We ignore method checks and use normal get_by_id optimizations.
- dispatch(1)
-
-
_llint_op_strcat:
traceExecution()
callSlowPath(_llint_slow_path_strcat)
dispatch(4)
-_llint_op_to_primitive:
+_llint_op_method_check:
traceExecution()
- loadi 8[PC], t2
- loadi 4[PC], t3
- loadConstantOrVariable(t2, t1, t0)
- bineq t1, CellTag, .opToPrimitiveIsImm
- loadp JSCell::m_structure[t0], t2
- bbneq Structure::m_typeInfo + TypeInfo::m_type[t2], StringType, .opToPrimitiveSlowCase
-.opToPrimitiveIsImm:
- storei t1, TagOffset[cfr, t3, 8]
- storei t0, PayloadOffset[cfr, t3, 8]
- dispatch(3)
-
-.opToPrimitiveSlowCase:
- callSlowPath(_llint_slow_path_to_primitive)
- dispatch(3)
+ # We ignore method checks and use normal get_by_id optimizations.
+ dispatch(1)
_llint_op_get_pnames:
@@ -2165,46 +715,6 @@ _llint_op_get_pnames:
dispatch(0) # The slow_path either advances the PC or jumps us to somewhere else.
-_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_structure[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_structure[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_push_scope:
traceExecution()
callSlowPath(_llint_slow_path_push_scope)
@@ -2223,27 +733,6 @@ _llint_op_push_new_scope:
dispatch(4)
-_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 JIT throwing protocol calls for the cfr to be in t0. The throwing
- # code must have known that we were throwing to the interpreter, and have
- # set JSGlobalData::targetInterpreterPCForThrow.
- move t0, cfr
- loadp JITStackFrame::globalData[sp], t3
- loadi JSGlobalData::targetInterpreterPCForThrow[t3], PC
- loadi JSGlobalData::exception + PayloadOffset[t3], t0
- loadi JSGlobalData::exception + TagOffset[t3], t1
- storei 0, JSGlobalData::exception + PayloadOffset[t3]
- storei EmptyValueTag, JSGlobalData::exception + TagOffset[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)
-
-
_llint_op_throw:
traceExecution()
callSlowPath(_llint_slow_path_throw)
@@ -2256,27 +745,6 @@ _llint_op_throw_reference_error:
dispatch(2)
-_llint_op_jsr:
- traceExecution()
- loadi 4[PC], t0
- addi 3 * 4, PC, t1
- storei t1, [cfr, t0, 8]
- dispatchBranch(8[PC])
-
-
-_llint_op_sret:
- traceExecution()
- loadi 4[PC], t0
- loadp [cfr, t0, 8], PC
- dispatch(0)
-
-
-_llint_op_debug:
- traceExecution()
- callSlowPath(_llint_slow_path_debug)
- dispatch(4)
-
-
_llint_op_profile_will_call:
traceExecution()
loadp JITStackFrame::enabledProfilerReference[sp], t0
@@ -2295,29 +763,18 @@ _llint_op_profile_did_call:
dispatch(2)
-_llint_op_end:
+_llint_op_debug:
traceExecution()
- checkSwitchToJITForEpilogue()
- loadi 4[PC], t0
- loadi TagOffset[cfr, t0, 8], t1
- loadi PayloadOffset[cfr, t0, 8], t0
- doReturn()
+ callSlowPath(_llint_slow_path_debug)
+ dispatch(4)
-_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 JITStackFrame::globalData[sp], t1
- loadp JSGlobalData::callFrameForThrow[t1], t0
- jmp JSGlobalData::targetMachinePCForThrow[t1]
+_llint_native_call_trampoline:
+ nativeCallTrampoline(NativeExecutable::m_function)
-_llint_throw_during_call_trampoline:
- preserveReturnAddressAfterCall(t2)
- loadp JITStackFrame::globalData[sp], t1
- loadp JSGlobalData::callFrameForThrow[t1], t0
- jmp JSGlobalData::targetMachinePCForThrow[t1]
+_llint_native_construct_trampoline:
+ nativeCallTrampoline(NativeExecutable::m_constructor)
# Lastly, make sure that we can link even though we don't support all opcodes.
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter.h b/Source/JavaScriptCore/llint/LowLevelInterpreter.h
index e5a54a45d..6383757cf 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter.h
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter.h
@@ -48,6 +48,10 @@ extern "C" void llint_generic_return_point();
extern "C" void llint_throw_from_slow_path_trampoline();
extern "C" void llint_throw_during_call_trampoline();
+// Native call trampolines
+extern "C" void llint_native_call_trampoline();
+extern "C" void llint_native_construct_trampoline();
+
#endif // ENABLE(LLINT)
#endif // LowLevelInterpreter_h
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
new file mode 100644
index 000000000..46c6226e5
--- /dev/null
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
@@ -0,0 +1,1653 @@
+# Copyright (C) 2011, 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.
+
+
+# Crash course on the language that this is written in (which I just call
+# "assembly" even though it's more than that):
+#
+# - Mostly gas-style operand ordering. The last operand tends to be the
+# destination. So "a := b" is written as "mov b, a". But unlike gas,
+# comparisons are in-order, so "if (a < b)" is written as
+# "bilt a, b, ...".
+#
+# - "b" = byte, "h" = 16-bit word, "i" = 32-bit word, "p" = pointer.
+# Currently this is just 32-bit so "i" and "p" are interchangeable
+# except when an op supports one but not the other.
+#
+# - In general, valid operands for macro invocations and instructions are
+# registers (eg "t0"), addresses (eg "4[t0]"), base-index addresses
+# (eg "7[t0, t1, 2]"), absolute addresses (eg "0xa0000000[]"), or labels
+# (eg "_foo" or ".foo"). Macro invocations can also take anonymous
+# macros as operands. Instructions cannot take anonymous macros.
+#
+# - Labels must have names that begin with either "_" or ".". A "." label
+# is local and gets renamed before code gen to minimize namespace
+# pollution. A "_" label is an extern symbol (i.e. ".globl"). The "_"
+# may or may not be removed during code gen depending on whether the asm
+# conventions for C name mangling on the target platform mandate a "_"
+# prefix.
+#
+# - A "macro" is a lambda expression, which may be either anonymous or
+# named. But this has caveats. "macro" can take zero or more arguments,
+# which may be macros or any valid operands, but it can only return
+# code. But you can do Turing-complete things via continuation passing
+# style: "macro foo (a, b) b(a) end foo(foo, foo)". Actually, don't do
+# that, since you'll just crash the assembler.
+#
+# - An "if" is a conditional on settings. Any identifier supplied in the
+# predicate of an "if" is assumed to be a #define that is available
+# during code gen. So you can't use "if" for computation in a macro, but
+# you can use it to select different pieces of code for different
+# platforms.
+#
+# - Arguments to macros follow lexical scoping rather than dynamic scoping.
+# Const's also follow lexical scoping and may override (hide) arguments
+# or other consts. All variables (arguments and constants) can be bound
+# to operands. Additionally, arguments (but not constants) can be bound
+# to macros.
+
+
+# Below we have a bunch of constant declarations. Each constant must have
+# a corresponding ASSERT() in LLIntData.cpp.
+
+
+# Value representation constants.
+const Int32Tag = -1
+const BooleanTag = -2
+const NullTag = -3
+const UndefinedTag = -4
+const CellTag = -5
+const EmptyValueTag = -6
+const DeletedValueTag = -7
+const LowestTag = DeletedValueTag
+
+
+# Utilities
+macro dispatch(advance)
+ addp advance * 4, PC
+ jmp [PC]
+end
+
+macro dispatchBranchWithOffset(pcOffset)
+ lshifti 2, pcOffset
+ addp pcOffset, PC
+ jmp [PC]
+end
+
+macro dispatchBranch(pcOffset)
+ loadi pcOffset, t0
+ dispatchBranchWithOffset(t0)
+end
+
+macro dispatchAfterCall()
+ loadi ArgumentCount + TagOffset[cfr], PC
+ jmp [PC]
+end
+
+macro cCall2(function, arg1, arg2)
+ if ARMv7
+ move arg1, t0
+ move arg2, t1
+ elsif X86
+ poke arg1, 0
+ poke arg2, 1
+ else
+ error
+ end
+ call function
+end
+
+# This barely works. arg3 and arg4 should probably be immediates.
+macro cCall4(function, arg1, arg2, arg3, arg4)
+ if ARMv7
+ move arg1, t0
+ move arg2, t1
+ move arg3, t2
+ move arg4, t3
+ elsif X86
+ poke arg1, 0
+ poke arg2, 1
+ poke arg3, 2
+ poke arg4, 3
+ else
+ error
+ end
+ call function
+end
+
+macro callSlowPath(slowPath)
+ cCall2(slowPath, cfr, PC)
+ move t0, PC
+ move t1, cfr
+end
+
+# Debugging operation if you'd like to print an operand in the instruction stream. fromWhere
+# should be an immediate integer - any integer you like; use it to identify the place you're
+# debugging from. operand should likewise be an immediate, and should identify the operand
+# in the instruction stream you'd like to print out.
+macro traceOperand(fromWhere, operand)
+ cCall4(_llint_trace_operand, cfr, PC, fromWhere, operand)
+ move t0, PC
+ move t1, cfr
+end
+
+# Debugging operation if you'd like to print the value of an operand in the instruction
+# stream. Same as traceOperand(), but assumes that the operand is a register, and prints its
+# value.
+macro traceValue(fromWhere, operand)
+ cCall4(_llint_trace_value, cfr, PC, fromWhere, operand)
+ move t0, PC
+ move t1, cfr
+end
+
+# Call a slowPath for call opcodes.
+macro callCallSlowPath(advance, slowPath, action)
+ addp advance * 4, PC, t0
+ storep t0, ArgumentCount + TagOffset[cfr]
+ cCall2(slowPath, cfr, PC)
+ move t1, cfr
+ action(t0)
+end
+
+macro checkSwitchToJITForLoop()
+ checkSwitchToJIT(
+ 1,
+ macro ()
+ storei PC, ArgumentCount + TagOffset[cfr]
+ cCall2(_llint_loop_osr, cfr, PC)
+ move t1, cfr
+ btpz t0, .recover
+ jmp t0
+ .recover:
+ loadi ArgumentCount + TagOffset[cfr], PC
+ end)
+end
+
+# Index, tag, and payload must be different registers. Index is not
+# changed.
+macro loadConstantOrVariable(index, tag, payload)
+ bigteq index, FirstConstantRegisterIndex, .constant
+ loadi TagOffset[cfr, index, 8], tag
+ loadi PayloadOffset[cfr, index, 8], payload
+ jmp .done
+.constant:
+ loadp CodeBlock[cfr], payload
+ loadp CodeBlock::m_constantRegisters + VectorBufferOffset[payload], payload
+ # There is a bit of evil here: if the index contains a value >= FirstConstantRegisterIndex,
+ # then value << 3 will be equal to (value - FirstConstantRegisterIndex) << 3.
+ loadp TagOffset[payload, index, 8], tag
+ loadp PayloadOffset[payload, index, 8], payload
+.done:
+end
+
+# Index and payload may be the same register. Index may be clobbered.
+macro loadConstantOrVariable2Reg(index, tag, payload)
+ bigteq index, FirstConstantRegisterIndex, .constant
+ loadi TagOffset[cfr, index, 8], tag
+ loadi PayloadOffset[cfr, index, 8], payload
+ jmp .done
+.constant:
+ loadp CodeBlock[cfr], tag
+ loadp CodeBlock::m_constantRegisters + VectorBufferOffset[tag], tag
+ # There is a bit of evil here: if the index contains a value >= FirstConstantRegisterIndex,
+ # then value << 3 will be equal to (value - FirstConstantRegisterIndex) << 3.
+ lshifti 3, index
+ addp index, tag
+ loadp PayloadOffset[tag], payload
+ loadp TagOffset[tag], tag
+.done:
+end
+
+macro loadConstantOrVariablePayloadTagCustom(index, tagCheck, payload)
+ bigteq index, FirstConstantRegisterIndex, .constant
+ tagCheck(TagOffset[cfr, index, 8])
+ loadi PayloadOffset[cfr, index, 8], payload
+ jmp .done
+.constant:
+ loadp CodeBlock[cfr], payload
+ loadp CodeBlock::m_constantRegisters + VectorBufferOffset[payload], payload
+ # There is a bit of evil here: if the index contains a value >= FirstConstantRegisterIndex,
+ # then value << 3 will be equal to (value - FirstConstantRegisterIndex) << 3.
+ tagCheck(TagOffset[payload, index, 8])
+ loadp PayloadOffset[payload, index, 8], payload
+.done:
+end
+
+# Index and payload must be different registers. Index is not mutated. Use
+# this if you know what the tag of the variable should be. Doing the tag
+# test as part of loading the variable reduces register use, but may not
+# be faster than doing loadConstantOrVariable followed by a branch on the
+# tag.
+macro loadConstantOrVariablePayload(index, expectedTag, payload, slow)
+ loadConstantOrVariablePayloadTagCustom(
+ index,
+ macro (actualTag) bineq actualTag, expectedTag, slow end,
+ payload)
+end
+
+macro loadConstantOrVariablePayloadUnchecked(index, payload)
+ loadConstantOrVariablePayloadTagCustom(
+ index,
+ macro (actualTag) end,
+ payload)
+end
+
+macro writeBarrier(tag, payload)
+ # Nothing to do, since we don't have a generational or incremental collector.
+end
+
+macro valueProfile(tag, payload, profile)
+ if VALUE_PROFILER
+ storei tag, ValueProfile::m_buckets + TagOffset[profile]
+ storei payload, ValueProfile::m_buckets + PayloadOffset[profile]
+ end
+end
+
+
+# Entrypoints into the interpreter
+
+# Expects that CodeBlock is in t1, which is what prologue() leaves behind.
+macro functionArityCheck(doneLabel, slow_path)
+ loadi PayloadOffset + ArgumentCount[cfr], t0
+ biaeq t0, CodeBlock::m_numParameters[t1], doneLabel
+ cCall2(slow_path, cfr, PC) # This slow_path has a simple protocol: t0 = 0 => no error, t0 != 0 => error
+ move t1, cfr
+ btiz t0, .continue
+ loadp JITStackFrame::globalData[sp], t1
+ loadp JSGlobalData::callFrameForThrow[t1], t0
+ jmp JSGlobalData::targetMachinePCForThrow[t1]
+.continue:
+ # Reload CodeBlock and PC, since the slow_path clobbered it.
+ loadp CodeBlock[cfr], t1
+ loadp CodeBlock::m_instructions[t1], PC
+ jmp doneLabel
+end
+
+
+# Instruction implementations
+
+_llint_op_enter:
+ traceExecution()
+ loadp CodeBlock[cfr], t2
+ loadi CodeBlock::m_numVars[t2], t2
+ btiz t2, .opEnterDone
+ move UndefinedTag, t0
+ move 0, t1
+.opEnterLoop:
+ subi 1, t2
+ storei t0, TagOffset[cfr, t2, 8]
+ storei t1, PayloadOffset[cfr, t2, 8]
+ btinz t2, .opEnterLoop
+.opEnterDone:
+ dispatch(1)
+
+
+_llint_op_create_activation:
+ 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)
+
+
+_llint_op_create_arguments:
+ traceExecution()
+ loadi 4[PC], t0
+ bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opCreateArgumentsDone
+ callSlowPath(_llint_slow_path_create_arguments)
+.opCreateArgumentsDone:
+ dispatch(2)
+
+
+_llint_op_create_this:
+ traceExecution()
+ loadi 8[PC], t0
+ assertNotConstant(t0)
+ bineq TagOffset[cfr, t0, 8], CellTag, .opCreateThisSlow
+ loadi PayloadOffset[cfr, t0, 8], t0
+ loadp JSCell::m_structure[t0], t1
+ bbb Structure::m_typeInfo + TypeInfo::m_type[t1], ObjectType, .opCreateThisSlow
+ loadp JSObject::m_inheritorID[t0], t2
+ btpz t2, .opCreateThisSlow
+ allocateBasicJSObject(JSFinalObjectSizeClassIndex, JSGlobalData::jsFinalObjectClassInfo, t2, t0, t1, t3, .opCreateThisSlow)
+ loadi 4[PC], t1
+ storei CellTag, TagOffset[cfr, t1, 8]
+ storei t0, PayloadOffset[cfr, t1, 8]
+ dispatch(3)
+
+.opCreateThisSlow:
+ callSlowPath(_llint_slow_path_create_this)
+ dispatch(3)
+
+
+_llint_op_get_callee:
+ traceExecution()
+ loadi 4[PC], t0
+ loadp PayloadOffset + Callee[cfr], t1
+ storei CellTag, TagOffset[cfr, t0, 8]
+ storei t1, PayloadOffset[cfr, t0, 8]
+ dispatch(2)
+
+
+_llint_op_convert_this:
+ traceExecution()
+ loadi 4[PC], t0
+ bineq TagOffset[cfr, t0, 8], CellTag, .opConvertThisSlow
+ loadi PayloadOffset[cfr, t0, 8], t0
+ loadp JSCell::m_structure[t0], t0
+ bbb Structure::m_typeInfo + TypeInfo::m_type[t0], ObjectType, .opConvertThisSlow
+ dispatch(2)
+
+.opConvertThisSlow:
+ callSlowPath(_llint_slow_path_convert_this)
+ dispatch(2)
+
+
+_llint_op_new_object:
+ traceExecution()
+ loadp CodeBlock[cfr], t0
+ loadp CodeBlock::m_globalObject[t0], t0
+ loadp JSGlobalObject::m_emptyObjectStructure[t0], t1
+ allocateBasicJSObject(JSFinalObjectSizeClassIndex, JSGlobalData::jsFinalObjectClassInfo, t1, t0, t2, t3, .opNewObjectSlow)
+ loadi 4[PC], t1
+ storei CellTag, TagOffset[cfr, t1, 8]
+ storei t0, PayloadOffset[cfr, t1, 8]
+ dispatch(2)
+
+.opNewObjectSlow:
+ callSlowPath(_llint_slow_path_new_object)
+ dispatch(2)
+
+
+_llint_op_mov:
+ 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)
+
+
+_llint_op_not:
+ traceExecution()
+ loadi 8[PC], t0
+ loadi 4[PC], t1
+ loadConstantOrVariable(t0, t2, t3)
+ bineq t2, BooleanTag, .opNotSlow
+ xori 1, t3
+ storei t2, TagOffset[cfr, t1, 8]
+ storei t3, PayloadOffset[cfr, t1, 8]
+ dispatch(3)
+
+.opNotSlow:
+ callSlowPath(_llint_slow_path_not)
+ dispatch(3)
+
+
+_llint_op_eq:
+ traceExecution()
+ loadi 12[PC], t2
+ loadi 8[PC], t0
+ loadConstantOrVariable(t2, t3, t1)
+ loadConstantOrVariable2Reg(t0, t2, t0)
+ bineq t2, t3, .opEqSlow
+ bieq t2, CellTag, .opEqSlow
+ bib t2, LowestTag, .opEqSlow
+ loadi 4[PC], t2
+ cieq t0, t1, t0
+ storei BooleanTag, TagOffset[cfr, t2, 8]
+ storei t0, PayloadOffset[cfr, t2, 8]
+ dispatch(4)
+
+.opEqSlow:
+ callSlowPath(_llint_slow_path_eq)
+ dispatch(4)
+
+
+_llint_op_eq_null:
+ traceExecution()
+ loadi 8[PC], t0
+ loadi 4[PC], t3
+ assertNotConstant(t0)
+ loadi TagOffset[cfr, t0, 8], t1
+ loadi PayloadOffset[cfr, t0, 8], t0
+ bineq t1, CellTag, .opEqNullImmediate
+ loadp JSCell::m_structure[t0], t1
+ tbnz Structure::m_typeInfo + TypeInfo::m_flags[t1], MasqueradesAsUndefined, t1
+ jmp .opEqNullNotImmediate
+.opEqNullImmediate:
+ cieq t1, NullTag, t2
+ cieq t1, UndefinedTag, t1
+ ori t2, t1
+.opEqNullNotImmediate:
+ storei BooleanTag, TagOffset[cfr, t3, 8]
+ storei t1, PayloadOffset[cfr, t3, 8]
+ dispatch(3)
+
+
+_llint_op_neq:
+ traceExecution()
+ loadi 12[PC], t2
+ loadi 8[PC], t0
+ loadConstantOrVariable(t2, t3, t1)
+ loadConstantOrVariable2Reg(t0, t2, t0)
+ bineq t2, t3, .opNeqSlow
+ bieq t2, CellTag, .opNeqSlow
+ bib t2, LowestTag, .opNeqSlow
+ loadi 4[PC], t2
+ cineq t0, t1, t0
+ storei BooleanTag, TagOffset[cfr, t2, 8]
+ storei t0, PayloadOffset[cfr, t2, 8]
+ dispatch(4)
+
+.opNeqSlow:
+ callSlowPath(_llint_slow_path_neq)
+ dispatch(4)
+
+
+_llint_op_neq_null:
+ traceExecution()
+ loadi 8[PC], t0
+ loadi 4[PC], t3
+ assertNotConstant(t0)
+ loadi TagOffset[cfr, t0, 8], t1
+ loadi PayloadOffset[cfr, t0, 8], t0
+ bineq t1, CellTag, .opNeqNullImmediate
+ loadp JSCell::m_structure[t0], t1
+ tbz Structure::m_typeInfo + TypeInfo::m_flags[t1], MasqueradesAsUndefined, t1
+ jmp .opNeqNullNotImmediate
+.opNeqNullImmediate:
+ cineq t1, NullTag, t2
+ cineq t1, UndefinedTag, t1
+ andi t2, t1
+.opNeqNullNotImmediate:
+ storei BooleanTag, TagOffset[cfr, t3, 8]
+ storei t1, PayloadOffset[cfr, t3, 8]
+ dispatch(3)
+
+
+macro strictEq(equalityOperation, slowPath)
+ loadi 12[PC], t2
+ loadi 8[PC], t0
+ loadConstantOrVariable(t2, t3, t1)
+ loadConstantOrVariable2Reg(t0, t2, t0)
+ bineq t2, t3, .slow
+ bib t2, LowestTag, .slow
+ bineq t2, CellTag, .notString
+ loadp JSCell::m_structure[t0], t2
+ loadp JSCell::m_structure[t1], t3
+ bbneq Structure::m_typeInfo + TypeInfo::m_type[t2], StringType, .notString
+ bbeq Structure::m_typeInfo + TypeInfo::m_type[t3], StringType, .slow
+.notString:
+ loadi 4[PC], t2
+ equalityOperation(t0, t1, t0)
+ storei BooleanTag, TagOffset[cfr, t2, 8]
+ storei t0, PayloadOffset[cfr, t2, 8]
+ dispatch(4)
+
+.slow:
+ callSlowPath(slowPath)
+ dispatch(4)
+end
+
+_llint_op_stricteq:
+ traceExecution()
+ strictEq(macro (left, right, result) cieq left, right, result end, _llint_slow_path_stricteq)
+
+
+_llint_op_nstricteq:
+ traceExecution()
+ strictEq(macro (left, right, result) cineq left, right, result end, _llint_slow_path_nstricteq)
+
+
+_llint_op_pre_inc:
+ traceExecution()
+ loadi 4[PC], t0
+ bineq TagOffset[cfr, t0, 8], Int32Tag, .opPreIncSlow
+ loadi PayloadOffset[cfr, t0, 8], t1
+ baddio 1, t1, .opPreIncSlow
+ storei t1, PayloadOffset[cfr, t0, 8]
+ dispatch(2)
+
+.opPreIncSlow:
+ callSlowPath(_llint_slow_path_pre_inc)
+ dispatch(2)
+
+
+_llint_op_pre_dec:
+ traceExecution()
+ loadi 4[PC], t0
+ bineq TagOffset[cfr, t0, 8], Int32Tag, .opPreDecSlow
+ loadi PayloadOffset[cfr, t0, 8], t1
+ bsubio 1, t1, .opPreDecSlow
+ storei t1, PayloadOffset[cfr, t0, 8]
+ dispatch(2)
+
+.opPreDecSlow:
+ callSlowPath(_llint_slow_path_pre_dec)
+ dispatch(2)
+
+
+_llint_op_post_inc:
+ traceExecution()
+ loadi 8[PC], t0
+ loadi 4[PC], t1
+ bineq TagOffset[cfr, t0, 8], Int32Tag, .opPostIncSlow
+ bieq t0, t1, .opPostIncDone
+ loadi PayloadOffset[cfr, t0, 8], t2
+ move t2, t3
+ baddio 1, t3, .opPostIncSlow
+ storei Int32Tag, TagOffset[cfr, t1, 8]
+ storei t2, PayloadOffset[cfr, t1, 8]
+ storei t3, PayloadOffset[cfr, t0, 8]
+.opPostIncDone:
+ dispatch(3)
+
+.opPostIncSlow:
+ callSlowPath(_llint_slow_path_post_inc)
+ dispatch(3)
+
+
+_llint_op_post_dec:
+ traceExecution()
+ loadi 8[PC], t0
+ loadi 4[PC], t1
+ bineq TagOffset[cfr, t0, 8], Int32Tag, .opPostDecSlow
+ bieq t0, t1, .opPostDecDone
+ loadi PayloadOffset[cfr, t0, 8], t2
+ move t2, t3
+ bsubio 1, t3, .opPostDecSlow
+ storei Int32Tag, TagOffset[cfr, t1, 8]
+ storei t2, PayloadOffset[cfr, t1, 8]
+ storei t3, PayloadOffset[cfr, t0, 8]
+.opPostDecDone:
+ dispatch(3)
+
+.opPostDecSlow:
+ callSlowPath(_llint_slow_path_post_dec)
+ dispatch(3)
+
+
+_llint_op_to_jsnumber:
+ traceExecution()
+ loadi 8[PC], t0
+ loadi 4[PC], t1
+ loadConstantOrVariable(t0, t2, t3)
+ bieq t2, Int32Tag, .opToJsnumberIsInt
+ biaeq t2, EmptyValueTag, .opToJsnumberSlow
+.opToJsnumberIsInt:
+ storei t2, TagOffset[cfr, t1, 8]
+ storei t3, PayloadOffset[cfr, t1, 8]
+ dispatch(3)
+
+.opToJsnumberSlow:
+ callSlowPath(_llint_slow_path_to_jsnumber)
+ dispatch(3)
+
+
+_llint_op_negate:
+ traceExecution()
+ loadi 8[PC], t0
+ loadi 4[PC], t3
+ loadConstantOrVariable(t0, t1, t2)
+ bineq t1, Int32Tag, .opNegateSrcNotInt
+ btiz t2, 0x7fffffff, .opNegateSlow
+ negi t2
+ storei Int32Tag, TagOffset[cfr, t3, 8]
+ storei t2, PayloadOffset[cfr, t3, 8]
+ dispatch(3)
+.opNegateSrcNotInt:
+ bia t1, LowestTag, .opNegateSlow
+ xori 0x80000000, t1
+ storei t1, TagOffset[cfr, t3, 8]
+ storei t2, PayloadOffset[cfr, t3, 8]
+ dispatch(3)
+
+.opNegateSlow:
+ callSlowPath(_llint_slow_path_negate)
+ dispatch(3)
+
+
+macro binaryOpCustomStore(integerOperationAndStore, doubleOperation, slowPath)
+ loadi 12[PC], t2
+ loadi 8[PC], t0
+ loadConstantOrVariable(t2, t3, t1)
+ loadConstantOrVariable2Reg(t0, t2, t0)
+ bineq t2, Int32Tag, .op1NotInt
+ bineq t3, Int32Tag, .op2NotInt
+ loadi 4[PC], t2
+ integerOperationAndStore(t3, t1, t0, .slow, t2)
+ dispatch(5)
+
+.op1NotInt:
+ # First operand is definitely not an int, the second operand could be anything.
+ bia t2, LowestTag, .slow
+ bib t3, LowestTag, .op1NotIntOp2Double
+ bineq t3, Int32Tag, .slow
+ ci2d t1, ft1
+ jmp .op1NotIntReady
+.op1NotIntOp2Double:
+ fii2d t1, t3, ft1
+.op1NotIntReady:
+ loadi 4[PC], t1
+ fii2d t0, t2, ft0
+ doubleOperation(ft1, ft0)
+ stored ft0, [cfr, t1, 8]
+ dispatch(5)
+
+.op2NotInt:
+ # First operand is definitely an int, the second operand is definitely not.
+ loadi 4[PC], t2
+ bia t3, LowestTag, .slow
+ ci2d t0, ft0
+ fii2d t1, t3, ft1
+ doubleOperation(ft1, ft0)
+ stored ft0, [cfr, t2, 8]
+ dispatch(5)
+
+.slow:
+ callSlowPath(slowPath)
+ dispatch(5)
+end
+
+macro binaryOp(integerOperation, doubleOperation, slowPath)
+ binaryOpCustomStore(
+ macro (int32Tag, left, right, slow, index)
+ integerOperation(left, right, slow)
+ storei int32Tag, TagOffset[cfr, index, 8]
+ storei right, PayloadOffset[cfr, index, 8]
+ end,
+ doubleOperation, slowPath)
+end
+
+_llint_op_add:
+ traceExecution()
+ binaryOp(
+ macro (left, right, slow) baddio left, right, slow end,
+ macro (left, right) addd left, right end,
+ _llint_slow_path_add)
+
+
+_llint_op_mul:
+ traceExecution()
+ binaryOpCustomStore(
+ macro (int32Tag, left, right, slow, index)
+ const scratch = int32Tag # We know that we can reuse the int32Tag register since it has a constant.
+ move right, scratch
+ bmulio left, scratch, slow
+ btinz scratch, .done
+ bilt left, 0, slow
+ bilt right, 0, slow
+ .done:
+ storei Int32Tag, TagOffset[cfr, index, 8]
+ storei scratch, PayloadOffset[cfr, index, 8]
+ end,
+ macro (left, right) muld left, right end,
+ _llint_slow_path_mul)
+
+
+_llint_op_sub:
+ traceExecution()
+ binaryOp(
+ macro (left, right, slow) bsubio left, right, slow end,
+ macro (left, right) subd left, right end,
+ _llint_slow_path_sub)
+
+
+_llint_op_div:
+ traceExecution()
+ binaryOpCustomStore(
+ macro (int32Tag, left, right, slow, index)
+ ci2d left, ft0
+ ci2d right, ft1
+ divd ft0, ft1
+ bcd2i ft1, right, .notInt
+ storei int32Tag, TagOffset[cfr, index, 8]
+ storei right, PayloadOffset[cfr, index, 8]
+ jmp .done
+ .notInt:
+ stored ft1, [cfr, index, 8]
+ .done:
+ end,
+ macro (left, right) divd left, right end,
+ _llint_slow_path_div)
+
+
+macro bitOp(operation, slowPath, advance)
+ loadi 12[PC], t2
+ loadi 8[PC], t0
+ loadConstantOrVariable(t2, t3, t1)
+ loadConstantOrVariable2Reg(t0, t2, t0)
+ bineq t3, Int32Tag, .slow
+ bineq t2, Int32Tag, .slow
+ loadi 4[PC], t2
+ operation(t1, t0, .slow)
+ storei t3, TagOffset[cfr, t2, 8]
+ storei t0, PayloadOffset[cfr, t2, 8]
+ dispatch(advance)
+
+.slow:
+ callSlowPath(slowPath)
+ dispatch(advance)
+end
+
+_llint_op_lshift:
+ traceExecution()
+ bitOp(
+ macro (left, right, slow) lshifti left, right end,
+ _llint_slow_path_lshift,
+ 4)
+
+
+_llint_op_rshift:
+ traceExecution()
+ bitOp(
+ macro (left, right, slow) rshifti left, right end,
+ _llint_slow_path_rshift,
+ 4)
+
+
+_llint_op_urshift:
+ traceExecution()
+ bitOp(
+ macro (left, right, slow)
+ urshifti left, right
+ bilt right, 0, slow
+ end,
+ _llint_slow_path_urshift,
+ 4)
+
+
+_llint_op_bitand:
+ traceExecution()
+ bitOp(
+ macro (left, right, slow) andi left, right end,
+ _llint_slow_path_bitand,
+ 5)
+
+
+_llint_op_bitxor:
+ traceExecution()
+ bitOp(
+ macro (left, right, slow) xori left, right end,
+ _llint_slow_path_bitxor,
+ 5)
+
+
+_llint_op_bitor:
+ traceExecution()
+ bitOp(
+ macro (left, right, slow) ori left, right end,
+ _llint_slow_path_bitor,
+ 5)
+
+
+_llint_op_check_has_instance:
+ traceExecution()
+ loadi 4[PC], t1
+ loadConstantOrVariablePayload(t1, CellTag, t0, .opCheckHasInstanceSlow)
+ loadp JSCell::m_structure[t0], t0
+ btbz Structure::m_typeInfo + TypeInfo::m_flags[t0], ImplementsHasInstance, .opCheckHasInstanceSlow
+ dispatch(2)
+
+.opCheckHasInstanceSlow:
+ callSlowPath(_llint_slow_path_check_has_instance)
+ dispatch(2)
+
+
+_llint_op_instanceof:
+ traceExecution()
+ # Check that baseVal implements the default HasInstance behavior.
+ # FIXME: This should be deprecated.
+ loadi 12[PC], t1
+ loadConstantOrVariablePayloadUnchecked(t1, t0)
+ loadp JSCell::m_structure[t0], t0
+ btbz Structure::m_typeInfo + TypeInfo::m_flags[t0], ImplementsDefaultHasInstance, .opInstanceofSlow
+
+ # Actually do the work.
+ loadi 16[PC], t0
+ loadi 4[PC], t3
+ loadConstantOrVariablePayload(t0, CellTag, t1, .opInstanceofSlow)
+ loadp JSCell::m_structure[t1], t2
+ bbb Structure::m_typeInfo + TypeInfo::m_type[t2], ObjectType, .opInstanceofSlow
+ loadi 8[PC], t0
+ loadConstantOrVariablePayload(t0, CellTag, t2, .opInstanceofSlow)
+
+ # Register state: t1 = prototype, t2 = value
+ move 1, t0
+.opInstanceofLoop:
+ loadp JSCell::m_structure[t2], t2
+ loadi Structure::m_prototype + PayloadOffset[t2], t2
+ bpeq t2, t1, .opInstanceofDone
+ btinz t2, .opInstanceofLoop
+
+ move 0, t0
+.opInstanceofDone:
+ storei BooleanTag, TagOffset[cfr, t3, 8]
+ storei t0, PayloadOffset[cfr, t3, 8]
+ dispatch(5)
+
+.opInstanceofSlow:
+ callSlowPath(_llint_slow_path_instanceof)
+ dispatch(5)
+
+
+macro resolveGlobal(size, slow)
+ # Operands are as follows:
+ # 4[PC] Destination for the load.
+ # 8[PC] Property identifier index in the code block.
+ # 12[PC] Structure pointer, initialized to 0 by bytecode generator.
+ # 16[PC] Offset in global object, initialized to 0 by bytecode generator.
+ loadp CodeBlock[cfr], t0
+ loadp CodeBlock::m_globalObject[t0], t0
+ loadp JSCell::m_structure[t0], t1
+ bpneq t1, 12[PC], slow
+ loadi 16[PC], t1
+ loadp JSObject::m_propertyStorage[t0], t0
+ loadi TagOffset[t0, t1, 8], t2
+ loadi PayloadOffset[t0, t1, 8], t3
+ loadi 4[PC], t0
+ storei t2, TagOffset[cfr, t0, 8]
+ storei t3, PayloadOffset[cfr, t0, 8]
+ loadi (size - 1) * 4[PC], t0
+ valueProfile(t2, t3, t0)
+end
+
+_llint_op_resolve_global:
+ traceExecution()
+ resolveGlobal(6, .opResolveGlobalSlow)
+ dispatch(6)
+
+.opResolveGlobalSlow:
+ callSlowPath(_llint_slow_path_resolve_global)
+ dispatch(6)
+
+
+# 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 getScope(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_needsFullScopeChain[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 ScopeChainNode::next[t0], t0
+.noActivation:
+ subi 1, t2
+
+ btiz t2, .done
+.loop:
+ scopeCheck(t0, t1)
+ loadp ScopeChainNode::next[t0], t0
+ subi 1, t2
+ btinz t2, .loop
+
+.done:
+end
+
+_llint_op_resolve_global_dynamic:
+ traceExecution()
+ loadp JITStackFrame::globalData[sp], t3
+ loadp JSGlobalData::activationStructure[t3], t3
+ getScope(
+ 20[PC],
+ macro (scope, scratch)
+ loadp ScopeChainNode::object[scope], scratch
+ bpneq JSCell::m_structure[scratch], t3, .opResolveGlobalDynamicSuperSlow
+ end)
+ resolveGlobal(7, .opResolveGlobalDynamicSlow)
+ dispatch(7)
+
+.opResolveGlobalDynamicSuperSlow:
+ callSlowPath(_llint_slow_path_resolve_for_resolve_global_dynamic)
+ dispatch(7)
+
+.opResolveGlobalDynamicSlow:
+ callSlowPath(_llint_slow_path_resolve_global_dynamic)
+ dispatch(7)
+
+
+_llint_op_get_scoped_var:
+ traceExecution()
+ # Operands are as follows:
+ # 4[PC] Destination for the load.
+ # 8[PC] Index of register in the scope.
+ # 12[PC] De Bruijin index.
+ getScope(12[PC], macro (scope, scratch) end)
+ loadi 4[PC], t1
+ loadi 8[PC], t2
+ loadp ScopeChainNode::object[t0], t0
+ loadp JSVariableObject::m_registers[t0], t0
+ loadi TagOffset[t0, t2, 8], t3
+ loadi PayloadOffset[t0, t2, 8], t0
+ storei t3, TagOffset[cfr, t1, 8]
+ storei t0, PayloadOffset[cfr, t1, 8]
+ loadi 16[PC], t1
+ valueProfile(t3, t0, t1)
+ dispatch(5)
+
+
+_llint_op_put_scoped_var:
+ traceExecution()
+ getScope(8[PC], macro (scope, scratch) end)
+ loadi 12[PC], t1
+ loadConstantOrVariable(t1, t3, t2)
+ loadi 4[PC], t1
+ writeBarrier(t3, t2)
+ loadp ScopeChainNode::object[t0], t0
+ loadp JSVariableObject::m_registers[t0], t0
+ storei t3, TagOffset[t0, t1, 8]
+ storei t2, PayloadOffset[t0, t1, 8]
+ dispatch(4)
+
+
+_llint_op_get_global_var:
+ traceExecution()
+ loadi 8[PC], t1
+ loadi 4[PC], t3
+ loadp CodeBlock[cfr], t0
+ loadp CodeBlock::m_globalObject[t0], t0
+ loadp JSGlobalObject::m_registers[t0], t0
+ loadi TagOffset[t0, t1, 8], t2
+ loadi PayloadOffset[t0, t1, 8], t1
+ storei t2, TagOffset[cfr, t3, 8]
+ storei t1, PayloadOffset[cfr, t3, 8]
+ loadi 12[PC], t3
+ valueProfile(t2, t1, t3)
+ dispatch(4)
+
+
+_llint_op_put_global_var:
+ traceExecution()
+ loadi 8[PC], t1
+ loadp CodeBlock[cfr], t0
+ loadp CodeBlock::m_globalObject[t0], t0
+ loadp JSGlobalObject::m_registers[t0], t0
+ loadConstantOrVariable(t1, t2, t3)
+ loadi 4[PC], t1
+ writeBarrier(t2, t3)
+ storei t2, TagOffset[t0, t1, 8]
+ storei t3, PayloadOffset[t0, t1, 8]
+ dispatch(3)
+
+
+_llint_op_get_by_id:
+ traceExecution()
+ # We only do monomorphic get_by_id caching for now, and we do not modify the
+ # opcode. We do, however, allow for the cache to change anytime if fails, since
+ # ping-ponging is free. At best we get lucky and the get_by_id will continue
+ # to take fast path on the new cache. At worst we take slow path, which is what
+ # we would have been doing anyway.
+ loadi 8[PC], t0
+ loadi 16[PC], t1
+ loadConstantOrVariablePayload(t0, CellTag, t3, .opGetByIdSlow)
+ loadi 20[PC], t2
+ loadp JSObject::m_propertyStorage[t3], t0
+ bpneq JSCell::m_structure[t3], t1, .opGetByIdSlow
+ loadi 4[PC], t1
+ loadi TagOffset[t0, t2], t3
+ loadi PayloadOffset[t0, t2], t2
+ storei t3, TagOffset[cfr, t1, 8]
+ storei t2, PayloadOffset[cfr, t1, 8]
+ loadi 32[PC], t1
+ valueProfile(t3, t2, t1)
+ dispatch(9)
+
+.opGetByIdSlow:
+ callSlowPath(_llint_slow_path_get_by_id)
+ 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)
+
+
+_llint_op_put_by_id:
+ traceExecution()
+ loadi 4[PC], t3
+ loadi 16[PC], t1
+ loadConstantOrVariablePayload(t3, CellTag, t0, .opPutByIdSlow)
+ loadi 12[PC], t2
+ loadp JSObject::m_propertyStorage[t0], t3
+ bpneq JSCell::m_structure[t0], t1, .opPutByIdSlow
+ loadi 20[PC], t1
+ loadConstantOrVariable2Reg(t2, t0, t2)
+ writeBarrier(t0, t2)
+ storei t0, TagOffset[t3, t1]
+ storei t2, PayloadOffset[t3, t1]
+ dispatch(9)
+
+.opPutByIdSlow:
+ callSlowPath(_llint_slow_path_put_by_id)
+ dispatch(9)
+
+
+macro putByIdTransition(additionalChecks)
+ traceExecution()
+ loadi 4[PC], t3
+ loadi 16[PC], t1
+ loadConstantOrVariablePayload(t3, CellTag, t0, .opPutByIdSlow)
+ loadi 12[PC], t2
+ bpneq JSCell::m_structure[t0], t1, .opPutByIdSlow
+ additionalChecks(t1, t3, .opPutByIdSlow)
+ loadi 20[PC], t1
+ loadp JSObject::m_propertyStorage[t0], t3
+ addp t1, t3
+ loadConstantOrVariable2Reg(t2, t1, t2)
+ writeBarrier(t1, t2)
+ storei t1, TagOffset[t3]
+ loadi 24[PC], t1
+ storei t2, PayloadOffset[t3]
+ storep t1, JSCell::m_structure[t0]
+ dispatch(9)
+end
+
+_llint_op_put_by_id_transition_direct:
+ putByIdTransition(macro (oldStructure, scratch, slow) end)
+
+
+_llint_op_put_by_id_transition_normal:
+ putByIdTransition(
+ macro (oldStructure, scratch, slow)
+ const protoCell = oldStructure # Reusing the oldStructure register for the proto
+
+ loadp 28[PC], scratch
+ assert(macro (ok) btpnz scratch, ok end)
+ loadp StructureChain::m_vector[scratch], scratch
+ assert(macro (ok) btpnz scratch, ok end)
+ bieq Structure::m_prototype + TagOffset[oldStructure], NullTag, .done
+ .loop:
+ loadi Structure::m_prototype + PayloadOffset[oldStructure], protoCell
+ loadp JSCell::m_structure[protoCell], oldStructure
+ bpneq oldStructure, [scratch], slow
+ addp 4, scratch
+ bineq Structure::m_prototype + TagOffset[oldStructure], NullTag, .loop
+ .done:
+ end)
+
+
+_llint_op_get_by_val:
+ traceExecution()
+ loadp CodeBlock[cfr], t1
+ loadi 8[PC], t2
+ loadi 12[PC], t3
+ loadp CodeBlock::m_globalData[t1], t1
+ loadConstantOrVariablePayload(t2, CellTag, t0, .opGetByValSlow)
+ loadp JSGlobalData::jsArrayClassInfo[t1], t2
+ loadConstantOrVariablePayload(t3, Int32Tag, t1, .opGetByValSlow)
+ bpneq [t0], t2, .opGetByValSlow
+ loadp JSArray::m_storage[t0], t3
+ biaeq t1, JSArray::m_vectorLength[t0], .opGetByValSlow
+ loadi 4[PC], t0
+ loadi ArrayStorage::m_vector + TagOffset[t3, t1, 8], t2
+ loadi ArrayStorage::m_vector + PayloadOffset[t3, t1, 8], t1
+ bieq t2, EmptyValueTag, .opGetByValSlow
+ storei t2, TagOffset[cfr, t0, 8]
+ storei t1, PayloadOffset[cfr, t0, 8]
+ loadi 16[PC], t0
+ valueProfile(t2, t1, t0)
+ dispatch(5)
+
+.opGetByValSlow:
+ callSlowPath(_llint_slow_path_get_by_val)
+ dispatch(5)
+
+
+_llint_op_get_argument_by_val:
+ 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
+ negi t2
+ 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]
+ dispatch(5)
+
+.opGetArgumentByValSlow:
+ callSlowPath(_llint_slow_path_get_argument_by_val)
+ dispatch(5)
+
+
+_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_structure[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
+ loadp JSObject::m_propertyStorage[t2], t2
+ loadi TagOffset[t2, t0, 8], t1
+ loadi PayloadOffset[t2, t0, 8], 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)
+
+
+_llint_op_put_by_val:
+ traceExecution()
+ loadi 4[PC], t0
+ loadConstantOrVariablePayload(t0, CellTag, t1, .opPutByValSlow)
+ loadi 8[PC], t0
+ loadConstantOrVariablePayload(t0, Int32Tag, t2, .opPutByValSlow)
+ loadp CodeBlock[cfr], t0
+ loadp CodeBlock::m_globalData[t0], t0
+ loadp JSGlobalData::jsArrayClassInfo[t0], t0
+ bpneq [t1], t0, .opPutByValSlow
+ biaeq t2, JSArray::m_vectorLength[t1], .opPutByValSlow
+ loadp JSArray::m_storage[t1], t0
+ bieq ArrayStorage::m_vector + TagOffset[t0, t2, 8], EmptyValueTag, .opPutByValEmpty
+.opPutByValStoreResult:
+ loadi 12[PC], t3
+ loadConstantOrVariable2Reg(t3, t1, t3)
+ writeBarrier(t1, t3)
+ storei t1, ArrayStorage::m_vector + TagOffset[t0, t2, 8]
+ storei t3, ArrayStorage::m_vector + PayloadOffset[t0, t2, 8]
+ dispatch(4)
+
+.opPutByValEmpty:
+ addi 1, ArrayStorage::m_numValuesInVector[t0]
+ bib t2, ArrayStorage::m_length[t0], .opPutByValStoreResult
+ addi 1, t2, t1
+ storei t1, ArrayStorage::m_length[t0]
+ jmp .opPutByValStoreResult
+
+.opPutByValSlow:
+ callSlowPath(_llint_slow_path_put_by_val)
+ dispatch(4)
+
+
+_llint_op_loop:
+ nop
+_llint_op_jmp:
+ traceExecution()
+ dispatchBranch(4[PC])
+
+
+macro jumpTrueOrFalse(conditionOp, slow)
+ loadi 4[PC], t1
+ loadConstantOrVariablePayload(t1, BooleanTag, t0, .slow)
+ conditionOp(t0, .target)
+ dispatch(3)
+
+.target:
+ dispatchBranch(8[PC])
+
+.slow:
+ callSlowPath(slow)
+ dispatch(0)
+end
+
+
+macro equalNull(cellHandler, immediateHandler)
+ loadi 4[PC], t0
+ assertNotConstant(t0)
+ loadi TagOffset[cfr, t0, 8], t1
+ loadi PayloadOffset[cfr, t0, 8], t0
+ bineq t1, CellTag, .immediate
+ loadp JSCell::m_structure[t0], t2
+ cellHandler(Structure::m_typeInfo + TypeInfo::m_flags[t2], .target)
+ dispatch(3)
+
+.target:
+ dispatchBranch(8[PC])
+
+.immediate:
+ ori 1, t1
+ immediateHandler(t1, .target)
+ dispatch(3)
+end
+
+_llint_op_jeq_null:
+ traceExecution()
+ equalNull(
+ macro (value, target) btbnz value, MasqueradesAsUndefined, target end,
+ macro (value, target) bieq value, NullTag, target end)
+
+
+_llint_op_jneq_null:
+ traceExecution()
+ equalNull(
+ macro (value, target) btbz value, MasqueradesAsUndefined, target end,
+ macro (value, target) bineq value, NullTag, target end)
+
+
+_llint_op_jneq_ptr:
+ traceExecution()
+ loadi 4[PC], t0
+ loadi 8[PC], t1
+ bineq TagOffset[cfr, t0, 8], CellTag, .opJneqPtrBranch
+ bpeq PayloadOffset[cfr, t0, 8], t1, .opJneqPtrFallThrough
+.opJneqPtrBranch:
+ dispatchBranch(12[PC])
+.opJneqPtrFallThrough:
+ dispatch(4)
+
+
+macro compare(integerCompare, doubleCompare, slowPath)
+ loadi 4[PC], t2
+ loadi 8[PC], t3
+ loadConstantOrVariable(t2, t0, t1)
+ loadConstantOrVariable2Reg(t3, t2, t3)
+ bineq t0, Int32Tag, .op1NotInt
+ bineq t2, Int32Tag, .op2NotInt
+ integerCompare(t1, t3, .jumpTarget)
+ dispatch(4)
+
+.op1NotInt:
+ bia t0, LowestTag, .slow
+ bib t2, LowestTag, .op1NotIntOp2Double
+ bineq t2, Int32Tag, .slow
+ ci2d t3, ft1
+ jmp .op1NotIntReady
+.op1NotIntOp2Double:
+ fii2d t3, t2, ft1
+.op1NotIntReady:
+ fii2d t1, t0, ft0
+ doubleCompare(ft0, ft1, .jumpTarget)
+ dispatch(4)
+
+.op2NotInt:
+ ci2d t1, ft0
+ bia t2, LowestTag, .slow
+ fii2d t3, t2, ft1
+ doubleCompare(ft0, ft1, .jumpTarget)
+ dispatch(4)
+
+.jumpTarget:
+ dispatchBranch(12[PC])
+
+.slow:
+ callSlowPath(slowPath)
+ dispatch(0)
+end
+
+
+_llint_op_switch_imm:
+ traceExecution()
+ loadi 12[PC], t2
+ loadi 4[PC], t3
+ loadConstantOrVariable(t2, t1, t0)
+ loadp CodeBlock[cfr], t2
+ loadp CodeBlock::m_rareData[t2], t2
+ muli sizeof SimpleJumpTable, t3 # FIXME: would be nice to peephole this!
+ loadp CodeBlock::RareData::m_immediateSwitchJumpTables + VectorBufferOffset[t2], t2
+ addp t3, t2
+ bineq t1, Int32Tag, .opSwitchImmNotInt
+ subi SimpleJumpTable::min[t2], t0
+ biaeq t0, SimpleJumpTable::branchOffsets + VectorSizeOffset[t2], .opSwitchImmFallThrough
+ loadp SimpleJumpTable::branchOffsets + VectorBufferOffset[t2], t3
+ loadi [t3, t0, 4], t1
+ btiz t1, .opSwitchImmFallThrough
+ dispatchBranchWithOffset(t1)
+
+.opSwitchImmNotInt:
+ bib t1, LowestTag, .opSwitchImmSlow # Go to slow path if it's a double.
+.opSwitchImmFallThrough:
+ dispatchBranch(8[PC])
+
+.opSwitchImmSlow:
+ callSlowPath(_llint_slow_path_switch_imm)
+ dispatch(0)
+
+
+_llint_op_switch_char:
+ traceExecution()
+ loadi 12[PC], t2
+ loadi 4[PC], t3
+ loadConstantOrVariable(t2, t1, t0)
+ loadp CodeBlock[cfr], t2
+ loadp CodeBlock::m_rareData[t2], t2
+ muli sizeof SimpleJumpTable, t3
+ loadp CodeBlock::RareData::m_characterSwitchJumpTables + VectorBufferOffset[t2], t2
+ addp t3, t2
+ bineq t1, CellTag, .opSwitchCharFallThrough
+ loadp JSCell::m_structure[t0], t1
+ bbneq Structure::m_typeInfo + TypeInfo::m_type[t1], StringType, .opSwitchCharFallThrough
+ loadp JSString::m_value[t0], t0
+ bineq StringImpl::m_length[t0], 1, .opSwitchCharFallThrough
+ loadp StringImpl::m_data8[t0], t1
+ btinz StringImpl::m_hashAndFlags[t0], HashFlags8BitBuffer, .opSwitchChar8Bit
+ loadh [t1], t0
+ jmp .opSwitchCharReady
+.opSwitchChar8Bit:
+ loadb [t1], t0
+.opSwitchCharReady:
+ subi SimpleJumpTable::min[t2], t0
+ biaeq t0, SimpleJumpTable::branchOffsets + VectorSizeOffset[t2], .opSwitchCharFallThrough
+ loadp SimpleJumpTable::branchOffsets + VectorBufferOffset[t2], t2
+ loadi [t2, t0, 4], t1
+ btiz t1, .opSwitchCharFallThrough
+ dispatchBranchWithOffset(t1)
+
+.opSwitchCharFallThrough:
+ dispatchBranch(8[PC])
+
+
+_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)
+
+
+macro doCall(slowPath)
+ loadi 4[PC], t0
+ loadi 16[PC], t1
+ loadp LLIntCallLinkInfo::callee[t1], t2
+ loadConstantOrVariablePayload(t0, CellTag, t3, .opCallSlow)
+ bineq t3, t2, .opCallSlow
+ loadi 12[PC], t3
+ addp 24, PC
+ lshifti 3, t3
+ addp cfr, t3 # t3 contains the new value of cfr
+ loadp JSFunction::m_scopeChain[t2], t0
+ storei t2, Callee + PayloadOffset[t3]
+ storei t0, ScopeChain + PayloadOffset[t3]
+ loadi 8 - 24[PC], t2
+ storei PC, ArgumentCount + TagOffset[cfr]
+ storep cfr, CallerFrame[t3]
+ storei t2, ArgumentCount + PayloadOffset[t3]
+ storei CellTag, Callee + TagOffset[t3]
+ storei CellTag, ScopeChain + TagOffset[t3]
+ move t3, cfr
+ call LLIntCallLinkInfo::machineCodeTarget[t1]
+ dispatchAfterCall()
+
+.opCallSlow:
+ slowPathForCall(6, slowPath)
+end
+
+
+_llint_op_tear_off_activation:
+ traceExecution()
+ loadi 4[PC], t0
+ loadi 8[PC], t1
+ bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opTearOffActivationCreated
+ bieq TagOffset[cfr, t1, 8], EmptyValueTag, .opTearOffActivationNotCreated
+.opTearOffActivationCreated:
+ callSlowPath(_llint_slow_path_tear_off_activation)
+.opTearOffActivationNotCreated:
+ dispatch(3)
+
+
+_llint_op_tear_off_arguments:
+ traceExecution()
+ loadi 4[PC], t0
+ subi 1, t0 # Get the unmodifiedArgumentsRegister
+ bieq TagOffset[cfr, t0, 8], EmptyValueTag, .opTearOffArgumentsNotCreated
+ callSlowPath(_llint_slow_path_tear_off_arguments)
+.opTearOffArgumentsNotCreated:
+ dispatch(2)
+
+
+_llint_op_ret:
+ traceExecution()
+ checkSwitchToJITForEpilogue()
+ loadi 4[PC], t2
+ loadConstantOrVariable(t2, t1, t0)
+ doReturn()
+
+
+_llint_op_call_put_result:
+ loadi 4[PC], t2
+ loadi 8[PC], t3
+ storei t1, TagOffset[cfr, t2, 8]
+ storei t0, PayloadOffset[cfr, t2, 8]
+ valueProfile(t1, t0, t3)
+ traceExecution() # Needs to be here because it would clobber t1, t0
+ dispatch(3)
+
+
+_llint_op_ret_object_or_this:
+ traceExecution()
+ checkSwitchToJITForEpilogue()
+ loadi 4[PC], t2
+ loadConstantOrVariable(t2, t1, t0)
+ bineq t1, CellTag, .opRetObjectOrThisNotObject
+ loadp JSCell::m_structure[t0], t2
+ bbb Structure::m_typeInfo + TypeInfo::m_type[t2], 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
+ loadp JSCell::m_structure[t0], t2
+ bbneq Structure::m_typeInfo + TypeInfo::m_type[t2], StringType, .opToPrimitiveSlowCase
+.opToPrimitiveIsImm:
+ storei t1, TagOffset[cfr, t3, 8]
+ storei t0, PayloadOffset[cfr, t3, 8]
+ dispatch(3)
+
+.opToPrimitiveSlowCase:
+ callSlowPath(_llint_slow_path_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_structure[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_structure[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 JIT throwing protocol calls for the cfr to be in t0. The throwing
+ # code must have known that we were throwing to the interpreter, and have
+ # set JSGlobalData::targetInterpreterPCForThrow.
+ move t0, cfr
+ loadp JITStackFrame::globalData[sp], t3
+ loadi JSGlobalData::targetInterpreterPCForThrow[t3], PC
+ loadi JSGlobalData::exception + PayloadOffset[t3], t0
+ loadi JSGlobalData::exception + TagOffset[t3], t1
+ storei 0, JSGlobalData::exception + PayloadOffset[t3]
+ storei EmptyValueTag, JSGlobalData::exception + TagOffset[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)
+
+
+_llint_op_jsr:
+ traceExecution()
+ loadi 4[PC], t0
+ addi 3 * 4, PC, t1
+ storei t1, [cfr, t0, 8]
+ dispatchBranch(8[PC])
+
+
+_llint_op_sret:
+ traceExecution()
+ loadi 4[PC], t0
+ loadp [cfr, t0, 8], PC
+ dispatch(0)
+
+
+_llint_op_end:
+ traceExecution()
+ checkSwitchToJITForEpilogue()
+ loadi 4[PC], t0
+ assertNotConstant(t0)
+ loadi TagOffset[cfr, t0, 8], t1
+ loadi PayloadOffset[cfr, t0, 8], t0
+ doReturn()
+
+
+_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 JITStackFrame::globalData[sp], t1
+ loadp JSGlobalData::callFrameForThrow[t1], t0
+ jmp JSGlobalData::targetMachinePCForThrow[t1]
+
+
+_llint_throw_during_call_trampoline:
+ preserveReturnAddressAfterCall(t2)
+ loadp JITStackFrame::globalData[sp], t1
+ loadp JSGlobalData::callFrameForThrow[t1], t0
+ jmp JSGlobalData::targetMachinePCForThrow[t1]
+
+
+macro nativeCallTrampoline(executableOffsetToFunction)
+ storep 0, CodeBlock[cfr]
+ loadp CallerFrame[cfr], t0
+ loadi ScopeChain + PayloadOffset[t0], t1
+ storei CellTag, ScopeChain + TagOffset[cfr]
+ storei t1, ScopeChain + PayloadOffset[cfr]
+ if X86
+ peek 0, t1
+ storep t1, ReturnPC[cfr]
+ move cfr, t2 # t2 = ecx
+ subp 16 - 4, sp
+ loadi Callee + PayloadOffset[cfr], t1
+ loadp JSFunction::m_executable[t1], t1
+ move t0, cfr
+ call executableOffsetToFunction[t1]
+ addp 16 - 4, sp
+ loadp JITStackFrame::globalData + 4[sp], t3
+ elsif ARMv7
+ move t0, t2
+ preserveReturnAddressAfterCall(t3)
+ storep t3, ReturnPC[cfr]
+ move cfr, t0
+ loadi Callee + PayloadOffset[cfr], t1
+ loadp JSFunction::m_executable[t1], t1
+ move t2, cfr
+ call executableOffsetToFunction[t1]
+ restoreReturnAddressBeforeReturn(t3)
+ loadp JITStackFrame::globalData[sp], t3
+ else
+ error
+ end
+ bineq JSGlobalData::exception + TagOffset[t3], EmptyValueTag, .exception
+ ret
+.exception:
+ preserveReturnAddressAfterCall(t1) # This is really only needed on X86
+ callSlowPath(_llint_throw_from_native_call)
+ jmp _llint_throw_from_slow_path_trampoline
+end
+
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
new file mode 100644
index 000000000..d8c931fa0
--- /dev/null
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
@@ -0,0 +1,1490 @@
+# Copyright (C) 2011, 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.
+
+
+# Some value representation constants.
+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
+
+# Utilities.
+macro dispatch(advance)
+ addp advance, PC
+ jmp [PB, PC, 8]
+end
+
+macro dispatchInt(advance)
+ addi advance, PC
+ jmp [PB, PC, 8]
+end
+
+macro dispatchAfterCall()
+ loadi ArgumentCount + TagOffset[cfr], PC
+ loadp CodeBlock[cfr], PB
+ loadp CodeBlock::m_instructions[PB], PB
+ jmp [PB, PC, 8]
+end
+
+macro cCall2(function, arg1, arg2)
+ move arg1, t5
+ move arg2, t4
+ call function
+end
+
+# This barely works. arg3 and arg4 should probably be immediates.
+macro cCall4(function, arg1, arg2, arg3, arg4)
+ move arg1, t5
+ move arg2, t4
+ move arg3, t1
+ move arg4, t2
+ call function
+end
+
+macro prepareStateForCCall()
+ leap [PB, PC, 8], PC
+ move PB, t3
+end
+
+macro restoreStateAfterCCall()
+ move t0, PC
+ move t1, cfr
+ move t3, PB
+ subp PB, PC
+ urshiftp 3, PC
+end
+
+macro callSlowPath(slowPath)
+ prepareStateForCCall()
+ cCall2(slowPath, cfr, PC)
+ restoreStateAfterCCall()
+end
+
+macro traceOperand(fromWhere, operand)
+ prepareStateForCCall()
+ cCall4(_llint_trace_operand, cfr, PC, fromWhere, operand)
+ restoreStateAfterCCall()
+end
+
+macro traceValue(fromWhere, operand)
+ prepareStateForCCall()
+ cCall4(_llint_trace_value, cfr, PC, fromWhere, operand)
+ restoreStateAfterCCall()
+end
+
+# Call a slow path for call call opcodes.
+macro callCallSlowPath(advance, slowPath, action)
+ addi advance, PC, t0
+ storei t0, ArgumentCount + TagOffset[cfr]
+ prepareStateForCCall()
+ cCall2(slowPath, cfr, PC)
+ move t1, cfr
+ action(t0)
+end
+
+macro checkSwitchToJITForLoop()
+ checkSwitchToJIT(
+ 1,
+ macro()
+ storei PC, ArgumentCount + TagOffset[cfr]
+ prepareStateForCCall()
+ cCall2(_llint_loop_osr, cfr, PC)
+ move t1, cfr
+ btpz t0, .recover
+ jmp t0
+ .recover:
+ loadp ArgumentCount + TagOffset[cfr], PC
+ end)
+end
+
+# Index and value must be different registers. Index may be clobbered.
+macro loadConstantOrVariable(index, value)
+ bpgteq index, FirstConstantRegisterIndex, .constant
+ loadp [cfr, index, 8], value
+ jmp .done
+.constant:
+ loadp CodeBlock[cfr], value
+ loadp CodeBlock::m_constantRegisters + VectorBufferOffset[value], value
+ subp FirstConstantRegisterIndex, index
+ loadp [value, index, 8], value
+.done:
+end
+
+macro loadConstantOrVariableInt32(index, value, slow)
+ loadConstantOrVariable(index, value)
+ bpb value, tagTypeNumber, slow
+end
+
+macro loadConstantOrVariableCell(index, value, slow)
+ loadConstantOrVariable(index, value)
+ btpnz value, tagMask, slow
+end
+
+macro writeBarrier(value)
+ # Nothing to do, since we don't have a generational or incremental collector.
+end
+
+macro valueProfile(value, profile)
+ if VALUE_PROFILER
+ storep value, ValueProfile::m_buckets[profile]
+ end
+end
+
+
+# Entrypoints into the interpreter.
+
+# Expects that CodeBlock is in t1, which is what prologue() leaves behind.
+macro functionArityCheck(doneLabel, slow_path)
+ loadi PayloadOffset + ArgumentCount[cfr], t0
+ biaeq t0, CodeBlock::m_numParameters[t1], doneLabel
+ prepareStateForCCall()
+ cCall2(slow_path, cfr, PC) # This slow_path has a simple protocol: t0 = 0 => no error, t0 != 0 => error
+ move t1, cfr
+ btiz t0, .continue
+ loadp JITStackFrame::globalData[sp], t1
+ loadp JSGlobalData::callFrameForThrow[t1], t0
+ jmp JSGlobalData::targetMachinePCForThrow[t1]
+.continue:
+ # Reload CodeBlock and reset PC, since the slow_path clobbered them.
+ loadp CodeBlock[cfr], t1
+ loadp CodeBlock::m_instructions[t1], PB
+ move 0, PC
+ jmp doneLabel
+end
+
+
+# Instruction implementations
+
+_llint_op_enter:
+ traceExecution()
+ loadp CodeBlock[cfr], t2
+ loadi CodeBlock::m_numVars[t2], t2
+ btiz t2, .opEnterDone
+ move ValueUndefined, t0
+.opEnterLoop:
+ subi 1, t2
+ storep t0, [cfr, t2, 8]
+ btinz t2, .opEnterLoop
+.opEnterDone:
+ dispatch(1)
+
+
+_llint_op_create_activation:
+ traceExecution()
+ loadis 8[PB, PC, 8], t0
+ bpneq [cfr, t0, 8], ValueEmpty, .opCreateActivationDone
+ callSlowPath(_llint_slow_path_create_activation)
+.opCreateActivationDone:
+ dispatch(2)
+
+
+_llint_op_init_lazy_reg:
+ traceExecution()
+ loadis 8[PB, PC, 8], t0
+ storep ValueEmpty, [cfr, t0, 8]
+ dispatch(2)
+
+
+_llint_op_create_arguments:
+ traceExecution()
+ loadis 8[PB, PC, 8], t0
+ bpneq [cfr, t0, 8], ValueEmpty, .opCreateArgumentsDone
+ callSlowPath(_llint_slow_path_create_arguments)
+.opCreateArgumentsDone:
+ dispatch(2)
+
+
+_llint_op_create_this:
+ traceExecution()
+ loadis 16[PB, PC, 8], t0
+ assertNotConstant(t0)
+ loadp [cfr, t0, 8], t0
+ btpnz t0, tagMask, .opCreateThisSlow
+ loadp JSCell::m_structure[t0], t1
+ bbb Structure::m_typeInfo + TypeInfo::m_type[t1], ObjectType, .opCreateThisSlow
+ loadp JSObject::m_inheritorID[t0], t2
+ btpz t2, .opCreateThisSlow
+ allocateBasicJSObject(JSFinalObjectSizeClassIndex, JSGlobalData::jsFinalObjectClassInfo, t2, t0, t1, t3, .opCreateThisSlow)
+ loadis 8[PB, PC, 8], t1
+ storep t0, [cfr, t1, 8]
+ dispatch(3)
+
+.opCreateThisSlow:
+ callSlowPath(_llint_slow_path_create_this)
+ dispatch(3)
+
+
+_llint_op_get_callee:
+ traceExecution()
+ loadis 8[PB, PC, 8], t0
+ loadp Callee[cfr], t1
+ storep t1, [cfr, t0, 8]
+ dispatch(2)
+
+
+_llint_op_convert_this:
+ traceExecution()
+ loadis 8[PB, PC, 8], t0
+ loadp [cfr, t0, 8], t0
+ btpnz t0, tagMask, .opConvertThisSlow
+ loadp JSCell::m_structure[t0], t0
+ bbb Structure::m_typeInfo + TypeInfo::m_type[t0], ObjectType, .opConvertThisSlow
+ dispatch(2)
+
+.opConvertThisSlow:
+ callSlowPath(_llint_slow_path_convert_this)
+ dispatch(2)
+
+
+_llint_op_new_object:
+ traceExecution()
+ loadp CodeBlock[cfr], t0
+ loadp CodeBlock::m_globalObject[t0], t0
+ loadp JSGlobalObject::m_emptyObjectStructure[t0], t1
+ allocateBasicJSObject(JSFinalObjectSizeClassIndex, JSGlobalData::jsFinalObjectClassInfo, t1, t0, t2, t3, .opNewObjectSlow)
+ loadis 8[PB, PC, 8], t1
+ storep t0, [cfr, t1, 8]
+ dispatch(2)
+
+.opNewObjectSlow:
+ callSlowPath(_llint_slow_path_new_object)
+ dispatch(2)
+
+
+_llint_op_mov:
+ traceExecution()
+ loadis 16[PB, PC, 8], t1
+ loadis 8[PB, PC, 8], t0
+ loadConstantOrVariable(t1, t2)
+ storep t2, [cfr, t0, 8]
+ dispatch(3)
+
+
+_llint_op_not:
+ traceExecution()
+ loadis 16[PB, PC, 8], t0
+ loadis 8[PB, PC, 8], t1
+ loadConstantOrVariable(t0, t2)
+ xorp ValueFalse, t2
+ btpnz t2, ~1, .opNotSlow
+ xorp ValueTrue, t2
+ storep t2, [cfr, t1, 8]
+ dispatch(3)
+
+.opNotSlow:
+ callSlowPath(_llint_slow_path_not)
+ dispatch(3)
+
+
+macro equalityComparison(integerComparison, slowPath)
+ traceExecution()
+ loadis 24[PB, PC, 8], t0
+ loadis 16[PB, PC, 8], t2
+ loadis 8[PB, PC, 8], t3
+ loadConstantOrVariableInt32(t0, t1, .slow)
+ loadConstantOrVariableInt32(t2, t0, .slow)
+ integerComparison(t0, t1, t0)
+ orp ValueFalse, t0
+ storep t0, [cfr, t3, 8]
+ dispatch(4)
+
+.slow:
+ callSlowPath(slowPath)
+ dispatch(4)
+end
+
+_llint_op_eq:
+ equalityComparison(
+ macro (left, right, result) cieq left, right, result end,
+ _llint_slow_path_eq)
+
+
+_llint_op_neq:
+ equalityComparison(
+ macro (left, right, result) cineq left, right, result end,
+ _llint_slow_path_neq)
+
+
+macro equalNullComparison()
+ loadis 16[PB, PC, 8], t0
+ loadp [cfr, t0, 8], t0
+ btpnz t0, tagMask, .immediate
+ loadp JSCell::m_structure[t0], t2
+ tbnz Structure::m_typeInfo + TypeInfo::m_flags[t2], MasqueradesAsUndefined, t0
+ jmp .done
+.immediate:
+ andp ~TagBitUndefined, t0
+ cpeq t0, ValueNull, t0
+.done:
+end
+
+_llint_op_eq_null:
+ traceExecution()
+ equalNullComparison()
+ loadis 8[PB, PC, 8], t1
+ orp ValueFalse, t0
+ storep t0, [cfr, t1, 8]
+ dispatch(3)
+
+
+_llint_op_neq_null:
+ traceExecution()
+ equalNullComparison()
+ loadis 8[PB, PC, 8], t1
+ xorp ValueTrue, t0
+ storep t0, [cfr, t1, 8]
+ dispatch(3)
+
+
+macro strictEq(equalityOperation, slowPath)
+ traceExecution()
+ loadis 24[PB, PC, 8], t0
+ loadis 16[PB, PC, 8], t2
+ loadConstantOrVariable(t0, t1)
+ loadConstantOrVariable(t2, t0)
+ move t0, t2
+ orp t1, t2
+ btpz t2, tagMask, .slow
+ bpaeq t0, tagTypeNumber, .leftOK
+ btpnz t0, tagTypeNumber, .slow
+.leftOK:
+ bpaeq t1, tagTypeNumber, .rightOK
+ btpnz t1, tagTypeNumber, .slow
+.rightOK:
+ equalityOperation(t0, t1, t0)
+ loadis 8[PB, PC, 8], t1
+ orp ValueFalse, t0
+ storep t0, [cfr, t1, 8]
+ dispatch(4)
+
+.slow:
+ callSlowPath(slowPath)
+ dispatch(4)
+end
+
+_llint_op_stricteq:
+ strictEq(
+ macro (left, right, result) cpeq left, right, result end,
+ _llint_slow_path_stricteq)
+
+
+_llint_op_nstricteq:
+ strictEq(
+ macro (left, right, result) cpneq left, right, result end,
+ _llint_slow_path_nstricteq)
+
+
+macro preOp(arithmeticOperation, slowPath)
+ traceExecution()
+ loadis 8[PB, PC, 8], t0
+ loadp [cfr, t0, 8], t1
+ bpb t1, tagTypeNumber, .slow
+ arithmeticOperation(t1, .slow)
+ orp tagTypeNumber, t1
+ storep t1, [cfr, t0, 8]
+ dispatch(2)
+
+.slow:
+ callSlowPath(slowPath)
+ dispatch(2)
+end
+
+_llint_op_pre_inc:
+ preOp(
+ macro (value, slow) baddio 1, value, slow end,
+ _llint_slow_path_pre_inc)
+
+
+_llint_op_pre_dec:
+ preOp(
+ macro (value, slow) bsubio 1, value, slow end,
+ _llint_slow_path_pre_dec)
+
+
+macro postOp(arithmeticOperation, slowPath)
+ traceExecution()
+ loadis 16[PB, PC, 8], t0
+ loadis 8[PB, PC, 8], t1
+ loadp [cfr, t0, 8], t2
+ bieq t0, t1, .done
+ bpb t2, tagTypeNumber, .slow
+ move t2, t3
+ arithmeticOperation(t3, .slow)
+ orp tagTypeNumber, t3
+ storep t2, [cfr, t1, 8]
+ storep t3, [cfr, t0, 8]
+.done:
+ dispatch(3)
+
+.slow:
+ callSlowPath(slowPath)
+ dispatch(3)
+end
+
+_llint_op_post_inc:
+ postOp(
+ macro (value, slow) baddio 1, value, slow end,
+ _llint_slow_path_post_inc)
+
+
+_llint_op_post_dec:
+ postOp(
+ macro (value, slow) bsubio 1, value, slow end,
+ _llint_slow_path_post_dec)
+
+
+_llint_op_to_jsnumber:
+ traceExecution()
+ loadis 16[PB, PC, 8], t0
+ loadis 8[PB, PC, 8], t1
+ loadConstantOrVariable(t0, t2)
+ bpaeq t2, tagTypeNumber, .opToJsnumberIsImmediate
+ btpz t2, tagTypeNumber, .opToJsnumberSlow
+.opToJsnumberIsImmediate:
+ storep t2, [cfr, t1, 8]
+ dispatch(3)
+
+.opToJsnumberSlow:
+ callSlowPath(_llint_slow_path_to_jsnumber)
+ dispatch(3)
+
+
+_llint_op_negate:
+ traceExecution()
+ loadis 16[PB, PC, 8], t0
+ loadis 8[PB, PC, 8], t1
+ loadConstantOrVariable(t0, t2)
+ bpb t2, tagTypeNumber, .opNegateNotInt
+ btiz t2, 0x7fffffff, .opNegateSlow
+ negi t2
+ orp tagTypeNumber, t2
+ storep t2, [cfr, t1, 8]
+ dispatch(3)
+.opNegateNotInt:
+ btpz t2, tagTypeNumber, .opNegateSlow
+ xorp 0x8000000000000000, t2
+ storep t2, [cfr, t1, 8]
+ dispatch(3)
+
+.opNegateSlow:
+ callSlowPath(_llint_slow_path_negate)
+ dispatch(3)
+
+
+macro binaryOpCustomStore(integerOperationAndStore, doubleOperation, slowPath)
+ loadis 24[PB, PC, 8], t0
+ loadis 16[PB, PC, 8], t2
+ loadConstantOrVariable(t0, t1)
+ loadConstantOrVariable(t2, t0)
+ bpb t0, tagTypeNumber, .op1NotInt
+ bpb t1, tagTypeNumber, .op2NotInt
+ loadis 8[PB, PC, 8], t2
+ integerOperationAndStore(t1, t0, .slow, t2)
+ dispatch(5)
+
+.op1NotInt:
+ # First operand is definitely not an int, the second operand could be anything.
+ btpz t0, tagTypeNumber, .slow
+ bpaeq t1, tagTypeNumber, .op1NotIntOp2Int
+ btpz t1, tagTypeNumber, .slow
+ addp tagTypeNumber, t1
+ fp2d t1, ft1
+ jmp .op1NotIntReady
+.op1NotIntOp2Int:
+ ci2d t1, ft1
+.op1NotIntReady:
+ loadis 8[PB, PC, 8], t2
+ addp tagTypeNumber, t0
+ fp2d t0, ft0
+ doubleOperation(ft1, ft0)
+ fd2p ft0, t0
+ subp tagTypeNumber, t0
+ storep t0, [cfr, t2, 8]
+ dispatch(5)
+
+.op2NotInt:
+ # First operand is definitely an int, the second is definitely not.
+ loadis 8[PB, PC, 8], t2
+ btpz t1, tagTypeNumber, .slow
+ ci2d t0, ft0
+ addp tagTypeNumber, t1
+ fp2d t1, ft1
+ doubleOperation(ft1, ft0)
+ fd2p ft0, t0
+ subp tagTypeNumber, t0
+ storep t0, [cfr, t2, 8]
+ dispatch(5)
+
+.slow:
+ callSlowPath(slowPath)
+ dispatch(5)
+end
+
+macro binaryOp(integerOperation, doubleOperation, slowPath)
+ binaryOpCustomStore(
+ macro (left, right, slow, index)
+ integerOperation(left, right, slow)
+ orp tagTypeNumber, right
+ storep right, [cfr, index, 8]
+ end,
+ doubleOperation, slowPath)
+end
+
+_llint_op_add:
+ traceExecution()
+ binaryOp(
+ macro (left, right, slow) baddio left, right, slow end,
+ macro (left, right) addd left, right end,
+ _llint_slow_path_add)
+
+
+_llint_op_mul:
+ traceExecution()
+ binaryOpCustomStore(
+ macro (left, right, slow, index)
+ # Assume t3 is scratchable.
+ move right, t3
+ bmulio left, t3, slow
+ btinz t3, .done
+ bilt left, 0, slow
+ bilt right, 0, slow
+ .done:
+ orp tagTypeNumber, t3
+ storep t3, [cfr, index, 8]
+ end,
+ macro (left, right) muld left, right end,
+ _llint_slow_path_mul)
+
+
+_llint_op_sub:
+ traceExecution()
+ binaryOp(
+ macro (left, right, slow) bsubio left, right, slow end,
+ macro (left, right) subd left, right end,
+ _llint_slow_path_sub)
+
+
+_llint_op_div:
+ traceExecution()
+ binaryOpCustomStore(
+ macro (left, right, slow, index)
+ # Assume t3 is scratchable.
+ btiz left, slow
+ btinz right, .intOK
+ bilt left, 0, slow
+ .intOK:
+ move left, t3
+ move right, t0
+ cdqi
+ idivi t3
+ btinz t1, slow
+ orp tagTypeNumber, t0
+ storep t0, [cfr, index, 8]
+ end,
+ macro (left, right) divd left, right end,
+ _llint_slow_path_div)
+
+
+macro bitOp(operation, slowPath, advance)
+ loadis 24[PB, PC, 8], t0
+ loadis 16[PB, PC, 8], t2
+ loadis 8[PB, PC, 8], t3
+ loadConstantOrVariable(t0, t1)
+ loadConstantOrVariable(t2, t0)
+ bpb t0, tagTypeNumber, .slow
+ bpb t1, tagTypeNumber, .slow
+ operation(t1, t0, .slow)
+ orp tagTypeNumber, t0
+ storep t0, [cfr, t3, 8]
+ dispatch(advance)
+
+.slow:
+ callSlowPath(slowPath)
+ dispatch(advance)
+end
+
+_llint_op_lshift:
+ traceExecution()
+ bitOp(
+ macro (left, right, slow) lshifti left, right end,
+ _llint_slow_path_lshift,
+ 4)
+
+
+_llint_op_rshift:
+ traceExecution()
+ bitOp(
+ macro (left, right, slow) rshifti left, right end,
+ _llint_slow_path_rshift,
+ 4)
+
+
+_llint_op_urshift:
+ traceExecution()
+ bitOp(
+ macro (left, right, slow)
+ urshifti left, right
+ bilt right, 0, slow
+ end,
+ _llint_slow_path_urshift,
+ 4)
+
+
+_llint_op_bitand:
+ traceExecution()
+ bitOp(
+ macro (left, right, slow) andi left, right end,
+ _llint_slow_path_bitand,
+ 5)
+
+
+_llint_op_bitxor:
+ traceExecution()
+ bitOp(
+ macro (left, right, slow) xori left, right end,
+ _llint_slow_path_bitxor,
+ 5)
+
+
+_llint_op_bitor:
+ traceExecution()
+ bitOp(
+ macro (left, right, slow) ori left, right end,
+ _llint_slow_path_bitor,
+ 5)
+
+
+_llint_op_check_has_instance:
+ traceExecution()
+ loadis 8[PB, PC, 8], t1
+ loadConstantOrVariableCell(t1, t0, .opCheckHasInstanceSlow)
+ loadp JSCell::m_structure[t0], t0
+ btbz Structure::m_typeInfo + TypeInfo::m_flags[t0], ImplementsHasInstance, .opCheckHasInstanceSlow
+ dispatch(2)
+
+.opCheckHasInstanceSlow:
+ callSlowPath(_llint_slow_path_check_has_instance)
+ dispatch(2)
+
+
+_llint_op_instanceof:
+ traceExecution()
+ # Check that baseVal implements the default HasInstance behavior.
+ # FIXME: This should be deprecated.
+ loadis 24[PB, PC, 8], t1
+ loadConstantOrVariable(t1, t0)
+ loadp JSCell::m_structure[t0], t0
+ btbz Structure::m_typeInfo + TypeInfo::m_flags[t0], ImplementsDefaultHasInstance, .opInstanceofSlow
+
+ # Actually do the work.
+ loadis 32[PB, PC, 8], t0
+ loadis 8[PB, PC, 8], t3
+ loadConstantOrVariableCell(t0, t1, .opInstanceofSlow)
+ loadp JSCell::m_structure[t1], t2
+ bbb Structure::m_typeInfo + TypeInfo::m_type[t2], ObjectType, .opInstanceofSlow
+ loadis 16[PB, PC, 8], t0
+ loadConstantOrVariableCell(t0, t2, .opInstanceofSlow)
+
+ # Register state: t1 = prototype, t2 = value
+ move 1, t0
+.opInstanceofLoop:
+ loadp JSCell::m_structure[t2], t2
+ loadp Structure::m_prototype[t2], t2
+ bpeq t2, t1, .opInstanceofDone
+ btpz t2, tagMask, .opInstanceofLoop
+
+ move 0, t0
+.opInstanceofDone:
+ orp ValueFalse, t0
+ storep t0, [cfr, t3, 8]
+ dispatch(5)
+
+.opInstanceofSlow:
+ callSlowPath(_llint_slow_path_instanceof)
+ dispatch(5)
+
+
+macro resolveGlobal(size, slow)
+ # Operands are as follows:
+ # 8[PB, PC, 8] Destination for the load.
+ # 16[PB, PC, 8] Property identifier index in the code block.
+ # 24[PB, PC, 8] Structure pointer, initialized to 0 by bytecode generator.
+ # 32[PB, PC, 8] Offset in global object, initialized to 0 by bytecode generator.
+ loadp CodeBlock[cfr], t0
+ loadp CodeBlock::m_globalObject[t0], t0
+ loadp JSCell::m_structure[t0], t1
+ bpneq t1, 24[PB, PC, 8], slow
+ loadis 32[PB, PC, 8], t1
+ loadp JSObject::m_propertyStorage[t0], t0
+ loadp [t0, t1, 8], t2
+ loadis 8[PB, PC, 8], t0
+ storep t2, [cfr, t0, 8]
+ loadp (size - 1) * 8[PB, PC, 8], t0
+ valueProfile(t2, t0)
+end
+
+_llint_op_resolve_global:
+ traceExecution()
+ resolveGlobal(6, .opResolveGlobalSlow)
+ dispatch(6)
+
+.opResolveGlobalSlow:
+ callSlowPath(_llint_slow_path_resolve_global)
+ dispatch(6)
+
+
+# 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 getScope(deBruijinIndexOperand, scopeCheck)
+ loadp ScopeChain[cfr], t0
+ loadis deBruijinIndexOperand, t2
+
+ btiz t2, .done
+
+ loadp CodeBlock[cfr], t1
+ bineq CodeBlock::m_codeType[t1], FunctionCode, .loop
+ btbz CodeBlock::m_needsFullScopeChain[t1], .loop
+
+ loadis CodeBlock::m_activationRegister[t1], t1
+
+ # Need to conditionally skip over one scope.
+ btpz [cfr, t1, 8], .noActivation
+ scopeCheck(t0, t1)
+ loadp ScopeChainNode::next[t0], t0
+.noActivation:
+ subi 1, t2
+
+ btiz t2, .done
+.loop:
+ scopeCheck(t0, t1)
+ loadp ScopeChainNode::next[t0], t0
+ subi 1, t2
+ btinz t2, .loop
+
+.done:
+end
+
+_llint_op_resolve_global_dynamic:
+ traceExecution()
+ loadp JITStackFrame::globalData[sp], t3
+ loadp JSGlobalData::activationStructure[t3], t3
+ getScope(
+ 40[PB, PC, 8],
+ macro (scope, scratch)
+ loadp ScopeChainNode::object[scope], scratch
+ bpneq JSCell::m_structure[scratch], t3, .opResolveGlobalDynamicSuperSlow
+ end)
+ resolveGlobal(7, .opResolveGlobalDynamicSlow)
+ dispatch(7)
+
+.opResolveGlobalDynamicSuperSlow:
+ callSlowPath(_llint_slow_path_resolve_for_resolve_global_dynamic)
+ dispatch(7)
+
+.opResolveGlobalDynamicSlow:
+ callSlowPath(_llint_slow_path_resolve_global_dynamic)
+ dispatch(7)
+
+
+_llint_op_get_scoped_var:
+ traceExecution()
+ # Operands are as follows:
+ # 8[PB, PC, 8] Destination for the load
+ # 16[PB, PC, 8] Index of register in the scope
+ # 24[PB, PC, 8] De Bruijin index.
+ getScope(24[PB, PC, 8], macro (scope, scratch) end)
+ loadis 8[PB, PC, 8], t1
+ loadis 16[PB, PC, 8], t2
+ loadp ScopeChainNode::object[t0], t0
+ loadp JSVariableObject::m_registers[t0], t0
+ loadp [t0, t2, 8], t3
+ storep t3, [cfr, t1, 8]
+ loadp 32[PB, PC, 8], t1
+ valueProfile(t3, t1)
+ dispatch(5)
+
+
+_llint_op_put_scoped_var:
+ traceExecution()
+ getScope(16[PB, PC, 8], macro (scope, scratch) end)
+ loadis 24[PB, PC, 8], t1
+ loadConstantOrVariable(t1, t3)
+ loadis 8[PB, PC, 8], t1
+ writeBarrier(t3)
+ loadp ScopeChainNode::object[t0], t0
+ loadp JSVariableObject::m_registers[t0], t0
+ storep t3, [t0, t1, 8]
+ dispatch(4)
+
+
+_llint_op_get_global_var:
+ traceExecution()
+ loadis 16[PB, PC, 8], t1
+ loadis 8[PB, PC, 8], t3
+ loadp CodeBlock[cfr], t0
+ loadp CodeBlock::m_globalObject[t0], t0
+ loadp JSGlobalObject::m_registers[t0], t0
+ loadp [t0, t1, 8], t2
+ storep t2, [cfr, t3, 8]
+ loadp 24[PB, PC, 8], t3
+ valueProfile(t2, t3)
+ dispatch(4)
+
+
+_llint_op_put_global_var:
+ traceExecution()
+ loadis 16[PB, PC, 8], t1
+ loadp CodeBlock[cfr], t0
+ loadp CodeBlock::m_globalObject[t0], t0
+ loadp JSGlobalObject::m_registers[t0], t0
+ loadConstantOrVariable(t1, t2)
+ loadis 8[PB, PC, 8], t1
+ writeBarrier(t2)
+ storep t2, [t0, t1, 8]
+ dispatch(3)
+
+
+_llint_op_get_by_id:
+ traceExecution()
+ # We only do monomorphic get_by_id caching for now, and we do not modify the
+ # opcode. We do, however, allow for the cache to change anytime if fails, since
+ # ping-ponging is free. At best we get lucky and the get_by_id will continue
+ # to take fast path on the new cache. At worst we take slow path, which is what
+ # we would have been doing anyway.
+ loadis 16[PB, PC, 8], t0
+ loadp 32[PB, PC, 8], t1
+ loadConstantOrVariableCell(t0, t3, .opGetByIdSlow)
+ loadis 40[PB, PC, 8], t2
+ loadp JSObject::m_propertyStorage[t3], t0
+ bpneq JSCell::m_structure[t3], t1, .opGetByIdSlow
+ loadis 8[PB, PC, 8], t1
+ loadp [t0, t2], t3
+ storep t3, [cfr, t1, 8]
+ loadp 64[PB, PC, 8], t1
+ valueProfile(t3, t1)
+ dispatch(9)
+
+.opGetByIdSlow:
+ callSlowPath(_llint_slow_path_get_by_id)
+ dispatch(9)
+
+
+_llint_op_get_arguments_length:
+ traceExecution()
+ loadis 16[PB, PC, 8], t0
+ loadis 8[PB, PC, 8], t1
+ btpnz [cfr, t0, 8], .opGetArgumentsLengthSlow
+ loadi ArgumentCount + PayloadOffset[cfr], t2
+ subi 1, t2
+ orp tagTypeNumber, t2
+ storep t2, [cfr, t1, 8]
+ dispatch(4)
+
+.opGetArgumentsLengthSlow:
+ callSlowPath(_llint_slow_path_get_arguments_length)
+ dispatch(4)
+
+
+_llint_op_put_by_id:
+ traceExecution()
+ loadis 8[PB, PC, 8], t3
+ loadp 32[PB, PC, 8], t1
+ loadConstantOrVariableCell(t3, t0, .opPutByIdSlow)
+ loadis 24[PB, PC, 8], t2
+ loadp JSObject::m_propertyStorage[t0], t3
+ bpneq JSCell::m_structure[t0], t1, .opPutByIdSlow
+ loadis 40[PB, PC, 8], t1
+ loadConstantOrVariable(t2, t0)
+ writeBarrier(t0)
+ storep t0, [t3, t1]
+ dispatch(9)
+
+.opPutByIdSlow:
+ callSlowPath(_llint_slow_path_put_by_id)
+ dispatch(9)
+
+
+macro putByIdTransition(additionalChecks)
+ traceExecution()
+ loadis 8[PB, PC, 8], t3
+ loadp 32[PB, PC, 8], t1
+ loadConstantOrVariableCell(t3, t0, .opPutByIdSlow)
+ loadis 24[PB, PC, 8], t2
+ bpneq JSCell::m_structure[t0], t1, .opPutByIdSlow
+ additionalChecks(t1, t3, .opPutByIdSlow)
+ loadis 40[PB, PC, 8], t1
+ loadp JSObject::m_propertyStorage[t0], t3
+ addp t1, t3
+ loadConstantOrVariable(t2, t1)
+ writeBarrier(t1)
+ storep t1, [t3]
+ loadp 48[PB, PC, 8], t1
+ storep t1, JSCell::m_structure[t0]
+ dispatch(9)
+end
+
+_llint_op_put_by_id_transition_direct:
+ putByIdTransition(macro (oldStructure, scratch, slow) end)
+
+
+_llint_op_put_by_id_transition_normal:
+ putByIdTransition(
+ macro (oldStructure, scratch, slow)
+ const protoCell = oldStructure # Reusing the oldStructure register for the proto
+ loadp 56[PB, PC, 8], scratch
+ assert(macro (ok) btpnz scratch, ok end)
+ loadp StructureChain::m_vector[scratch], scratch
+ assert(macro (ok) btpnz scratch, ok end)
+ bpeq Structure::m_prototype[oldStructure], ValueNull, .done
+ .loop:
+ loadp Structure::m_prototype[oldStructure], protoCell
+ loadp JSCell::m_structure[protoCell], oldStructure
+ bpneq oldStructure, [scratch], slow
+ addp 8, scratch
+ bpneq Structure::m_prototype[oldStructure], ValueNull, .loop
+ .done:
+ end)
+
+
+_llint_op_get_by_val:
+ traceExecution()
+ loadp CodeBlock[cfr], t1
+ loadis 16[PB, PC, 8], t2
+ loadis 24[PB, PC, 8], t3
+ loadp CodeBlock::m_globalData[t1], t1
+ loadConstantOrVariableCell(t2, t0, .opGetByValSlow)
+ loadp JSGlobalData::jsArrayClassInfo[t1], t2
+ loadConstantOrVariableInt32(t3, t1, .opGetByValSlow)
+ sxi2p t1, t1
+ bpneq [t0], t2, .opGetByValSlow
+ loadp JSArray::m_storage[t0], t3
+ biaeq t1, JSArray::m_vectorLength[t0], .opGetByValSlow
+ loadis 8[PB, PC, 8], t0
+ loadp ArrayStorage::m_vector[t3, t1, 8], t2
+ btpz t2, .opGetByValSlow
+ storep t2, [cfr, t0, 8]
+ loadp 32[PB, PC, 8], t0
+ valueProfile(t2, t0)
+ dispatch(5)
+
+.opGetByValSlow:
+ callSlowPath(_llint_slow_path_get_by_val)
+ dispatch(5)
+
+
+_llint_op_get_argument_by_val:
+ traceExecution()
+ loadis 16[PB, PC, 8], t0
+ loadis 24[PB, PC, 8], t1
+ btpnz [cfr, t0, 8], .opGetArgumentByValSlow
+ loadConstantOrVariableInt32(t1, t2, .opGetArgumentByValSlow)
+ addi 1, t2
+ loadi ArgumentCount + PayloadOffset[cfr], t1
+ biaeq t2, t1, .opGetArgumentByValSlow
+ negi t2
+ sxi2p t2, t2
+ loadis 8[PB, PC, 8], t3
+ loadp ThisArgumentOffset[cfr, t2, 8], t0
+ storep t0, [cfr, t3, 8]
+ dispatch(5)
+
+.opGetArgumentByValSlow:
+ callSlowPath(_llint_slow_path_get_argument_by_val)
+ dispatch(5)
+
+
+_llint_op_get_by_pname:
+ traceExecution()
+ loadis 24[PB, PC, 8], t1
+ loadConstantOrVariable(t1, t0)
+ loadis 32[PB, PC, 8], t1
+ assertNotConstant(t1)
+ bpneq t0, [cfr, t1, 8], .opGetByPnameSlow
+ loadis 16[PB, PC, 8], t2
+ loadis 40[PB, PC, 8], t3
+ loadConstantOrVariableCell(t2, t0, .opGetByPnameSlow)
+ assertNotConstant(t3)
+ loadp [cfr, t3, 8], t1
+ loadp JSCell::m_structure[t0], t2
+ bpneq t2, JSPropertyNameIterator::m_cachedStructure[t1], .opGetByPnameSlow
+ loadis 48[PB, PC, 8], t3
+ loadi PayloadOffset[cfr, t3, 8], t3
+ subi 1, t3
+ biaeq t3, JSPropertyNameIterator::m_numCacheableSlots[t1], .opGetByPnameSlow
+ loadp JSObject::m_propertyStorage[t0], t0
+ loadp [t0, t3, 8], t0
+ loadis 8[PB, PC, 8], t1
+ storep t0, [cfr, t1, 8]
+ dispatch(7)
+
+.opGetByPnameSlow:
+ callSlowPath(_llint_slow_path_get_by_pname)
+ dispatch(7)
+
+
+_llint_op_put_by_val:
+ traceExecution()
+ loadis 8[PB, PC, 8], t0
+ loadConstantOrVariableCell(t0, t1, .opPutByValSlow)
+ loadis 16[PB, PC, 8], t0
+ loadConstantOrVariableInt32(t0, t2, .opPutByValSlow)
+ sxi2p t2, t2
+ loadp CodeBlock[cfr], t0
+ loadp CodeBlock::m_globalData[t0], t0
+ loadp JSGlobalData::jsArrayClassInfo[t0], t0
+ bpneq [t1], t0, .opPutByValSlow
+ biaeq t2, JSArray::m_vectorLength[t1], .opPutByValSlow
+ loadp JSArray::m_storage[t1], t0
+ btpz ArrayStorage::m_vector[t0, t2, 8], .opPutByValEmpty
+.opPutByValStoreResult:
+ loadis 24[PB, PC, 8], t3
+ loadConstantOrVariable(t3, t1)
+ writeBarrier(t1)
+ storep t1, ArrayStorage::m_vector[t0, t2, 8]
+ dispatch(4)
+
+.opPutByValEmpty:
+ addi 1, ArrayStorage::m_numValuesInVector[t0]
+ bib t2, ArrayStorage::m_length[t0], .opPutByValStoreResult
+ addi 1, t2, t1
+ storei t1, ArrayStorage::m_length[t0]
+ jmp .opPutByValStoreResult
+
+.opPutByValSlow:
+ callSlowPath(_llint_slow_path_put_by_val)
+ dispatch(4)
+
+
+_llint_op_loop:
+ nop
+_llint_op_jmp:
+ traceExecution()
+ dispatchInt(8[PB, PC, 8])
+
+
+macro jumpTrueOrFalse(conditionOp, slow)
+ loadis 8[PB, PC, 8], t1
+ loadConstantOrVariable(t1, t0)
+ xorp ValueFalse, t0
+ btpnz t0, -1, .slow
+ conditionOp(t0, .target)
+ dispatch(3)
+
+.target:
+ dispatchInt(16[PB, PC, 8])
+
+.slow:
+ callSlowPath(slow)
+ dispatch(0)
+end
+
+
+macro equalNull(cellHandler, immediateHandler)
+ loadis 8[PB, PC, 8], t0
+ assertNotConstant(t0)
+ loadp [cfr, t0, 8], t0
+ btpnz t0, tagMask, .immediate
+ loadp JSCell::m_structure[t0], t2
+ cellHandler(Structure::m_typeInfo + TypeInfo::m_flags[t2], .target)
+ dispatch(3)
+
+.target:
+ dispatch(16[PB, PC, 8])
+
+.immediate:
+ andp ~TagBitUndefined, t0
+ immediateHandler(t0, .target)
+ dispatch(3)
+end
+
+_llint_op_jeq_null:
+ traceExecution()
+ equalNull(
+ macro (value, target) btbnz value, MasqueradesAsUndefined, target end,
+ macro (value, target) bpeq value, ValueNull, target end)
+
+
+_llint_op_jneq_null:
+ traceExecution()
+ equalNull(
+ macro (value, target) btbz value, MasqueradesAsUndefined, target end,
+ macro (value, target) bpneq value, ValueNull, target end)
+
+
+_llint_op_jneq_ptr:
+ traceExecution()
+ loadis 8[PB, PC, 8], t0
+ loadp 16[PB, PC, 8], t1
+ bpneq t1, [cfr, t0, 8], .opJneqPtrTarget
+ dispatch(4)
+
+.opJneqPtrTarget:
+ dispatchInt(24[PB, PC, 8])
+
+
+macro compare(integerCompare, doubleCompare, slowPath)
+ loadis 8[PB, PC, 8], t2
+ loadis 16[PB, PC, 8], t3
+ loadConstantOrVariable(t2, t0)
+ loadConstantOrVariable(t3, t1)
+ bpb t0, tagTypeNumber, .op1NotInt
+ bpb t1, tagTypeNumber, .op2NotInt
+ integerCompare(t0, t1, .jumpTarget)
+ dispatch(4)
+
+.op1NotInt:
+ btpz t0, tagTypeNumber, .slow
+ bpb t1, tagTypeNumber, .op1NotIntOp2NotInt
+ ci2d t1, ft1
+ jmp .op1NotIntReady
+.op1NotIntOp2NotInt:
+ btpz t1, tagTypeNumber, .slow
+ addp tagTypeNumber, t1
+ fp2d t1, ft1
+.op1NotIntReady:
+ addp tagTypeNumber, t0
+ fp2d t0, ft0
+ doubleCompare(ft0, ft1, .jumpTarget)
+ dispatch(4)
+
+.op2NotInt:
+ ci2d t0, ft0
+ btpz t1, tagTypeNumber, .slow
+ addp tagTypeNumber, t1
+ fp2d t1, ft1
+ doubleCompare(ft0, ft1, .jumpTarget)
+ dispatch(4)
+
+.jumpTarget:
+ dispatchInt(24[PB, PC, 8])
+
+.slow:
+ callSlowPath(slowPath)
+ dispatch(0)
+end
+
+
+_llint_op_switch_imm:
+ traceExecution()
+ loadis 24[PB, PC, 8], t2
+ loadis 8[PB, PC, 8], t3
+ loadConstantOrVariable(t2, t1)
+ loadp CodeBlock[cfr], t2
+ loadp CodeBlock::m_rareData[t2], t2
+ muli sizeof SimpleJumpTable, t3 # FIXME: would be nice to peephole this!
+ loadp CodeBlock::RareData::m_immediateSwitchJumpTables + VectorBufferOffset[t2], t2
+ addp t3, t2
+ bpb t1, tagTypeNumber, .opSwitchImmNotInt
+ subi SimpleJumpTable::min[t2], t1
+ biaeq t1, SimpleJumpTable::branchOffsets + VectorSizeOffset[t2], .opSwitchImmFallThrough
+ loadp SimpleJumpTable::branchOffsets + VectorBufferOffset[t2], t3
+ loadis [t3, t1, 4], t1
+ btiz t1, .opSwitchImmFallThrough
+ dispatch(t1)
+
+.opSwitchImmNotInt:
+ btpnz t1, tagTypeNumber, .opSwitchImmSlow # Go slow if it's a double.
+.opSwitchImmFallThrough:
+ dispatchInt(16[PB, PC, 8])
+
+.opSwitchImmSlow:
+ callSlowPath(_llint_slow_path_switch_imm)
+ dispatch(0)
+
+
+_llint_op_switch_char:
+ traceExecution()
+ loadis 24[PB, PC, 8], t2
+ loadis 8[PB, PC, 8], t3
+ loadConstantOrVariable(t2, t1)
+ loadp CodeBlock[cfr], t2
+ loadp CodeBlock::m_rareData[t2], t2
+ muli sizeof SimpleJumpTable, t3
+ loadp CodeBlock::RareData::m_characterSwitchJumpTables + VectorBufferOffset[t2], t2
+ addp t3, t2
+ btpnz t1, tagMask, .opSwitchCharFallThrough
+ loadp JSCell::m_structure[t1], t0
+ bbneq Structure::m_typeInfo + TypeInfo::m_type[t0], StringType, .opSwitchCharFallThrough
+ loadp JSString::m_value[t1], t0
+ bineq StringImpl::m_length[t0], 1, .opSwitchCharFallThrough
+ loadp StringImpl::m_data8[t0], t1
+ btinz StringImpl::m_hashAndFlags[t0], HashFlags8BitBuffer, .opSwitchChar8Bit
+ loadh [t1], t0
+ jmp .opSwitchCharReady
+.opSwitchChar8Bit:
+ loadb [t1], t0
+.opSwitchCharReady:
+ subi SimpleJumpTable::min[t2], t0
+ biaeq t0, SimpleJumpTable::branchOffsets + VectorSizeOffset[t2], .opSwitchCharFallThrough
+ loadp SimpleJumpTable::branchOffsets + VectorBufferOffset[t2], t2
+ loadis [t2, t0, 4], t1
+ btiz t1, .opSwitchCharFallThrough
+ dispatch(t1)
+
+.opSwitchCharFallThrough:
+ dispatchInt(16[PB, PC, 8])
+
+
+_llint_op_new_func:
+ traceExecution()
+ btiz 24[PB, PC, 8], .opNewFuncUnchecked
+ loadis 8[PB, PC, 8], t1
+ btpnz [cfr, t1, 8], .opNewFuncDone
+.opNewFuncUnchecked:
+ callSlowPath(_llint_slow_path_new_func)
+.opNewFuncDone:
+ dispatch(4)
+
+
+macro doCall(slowPath)
+ loadis 8[PB, PC, 8], t0
+ loadp 32[PB, PC, 8], t1
+ loadp LLIntCallLinkInfo::callee[t1], t2
+ loadConstantOrVariable(t0, t3)
+ bpneq t3, t2, .opCallSlow
+ loadis 24[PB, PC, 8], t3
+ addi 6, PC
+ lshifti 3, t3
+ addp cfr, t3
+ loadp JSFunction::m_scopeChain[t2], t0
+ storep t2, Callee[t3]
+ storep t0, ScopeChain[t3]
+ loadis 16 - 48[PB, PC, 8], t2
+ storei PC, ArgumentCount + TagOffset[cfr]
+ storep cfr, CallerFrame[t3]
+ storei t2, ArgumentCount + PayloadOffset[t3]
+ move t3, cfr
+ call LLIntCallLinkInfo::machineCodeTarget[t1]
+ dispatchAfterCall()
+
+.opCallSlow:
+ slowPathForCall(6, slowPath)
+end
+
+
+_llint_op_tear_off_activation:
+ traceExecution()
+ loadis 8[PB, PC, 8], t0
+ loadis 16[PB, PC, 8], t1
+ btpnz [cfr, t0, 8], .opTearOffActivationCreated
+ btpz [cfr, t1, 8], .opTearOffActivationNotCreated
+.opTearOffActivationCreated:
+ callSlowPath(_llint_slow_path_tear_off_activation)
+.opTearOffActivationNotCreated:
+ dispatch(3)
+
+
+_llint_op_tear_off_arguments:
+ traceExecution()
+ loadis 8[PB, PC, 8], t0
+ subi 1, t0 # Get the unmodifiedArgumentsRegister
+ btpz [cfr, t0, 8], .opTearOffArgumentsNotCreated
+ callSlowPath(_llint_slow_path_tear_off_arguments)
+.opTearOffArgumentsNotCreated:
+ dispatch(2)
+
+
+_llint_op_ret:
+ traceExecution()
+ checkSwitchToJITForEpilogue()
+ loadis 8[PB, PC, 8], t2
+ loadConstantOrVariable(t2, t0)
+ doReturn()
+
+
+_llint_op_call_put_result:
+ loadis 8[PB, PC, 8], t2
+ loadp 16[PB, PC, 8], t3
+ storep t0, [cfr, t2, 8]
+ valueProfile(t0, t3)
+ traceExecution()
+ dispatch(3)
+
+
+_llint_op_ret_object_or_this:
+ traceExecution()
+ checkSwitchToJITForEpilogue()
+ loadis 8[PB, PC, 8], t2
+ loadConstantOrVariable(t2, t0)
+ btpnz t0, tagMask, .opRetObjectOrThisNotObject
+ loadp JSCell::m_structure[t0], t2
+ bbb Structure::m_typeInfo + TypeInfo::m_type[t2], ObjectType, .opRetObjectOrThisNotObject
+ doReturn()
+
+.opRetObjectOrThisNotObject:
+ loadis 16[PB, PC, 8], t2
+ loadConstantOrVariable(t2, t0)
+ doReturn()
+
+
+_llint_op_to_primitive:
+ traceExecution()
+ loadis 16[PB, PC, 8], t2
+ loadis 8[PB, PC, 8], t3
+ loadConstantOrVariable(t2, t0)
+ btpnz t0, tagMask, .opToPrimitiveIsImm
+ loadp JSCell::m_structure[t0], t2
+ bbneq Structure::m_typeInfo + TypeInfo::m_type[t2], StringType, .opToPrimitiveSlowCase
+.opToPrimitiveIsImm:
+ storep t0, [cfr, t3, 8]
+ dispatch(3)
+
+.opToPrimitiveSlowCase:
+ callSlowPath(_llint_slow_path_to_primitive)
+ dispatch(3)
+
+
+_llint_op_next_pname:
+ traceExecution()
+ loadis 24[PB, PC, 8], t1
+ loadis 32[PB, PC, 8], t2
+ assertNotConstant(t1)
+ assertNotConstant(t2)
+ loadi PayloadOffset[cfr, t1, 8], t0
+ bieq t0, PayloadOffset[cfr, t2, 8], .opNextPnameEnd
+ loadis 40[PB, PC, 8], t2
+ assertNotConstant(t2)
+ loadp [cfr, t2, 8], t2
+ loadp JSPropertyNameIterator::m_jsStrings[t2], t3
+ loadp [t3, t0, 8], t3
+ addi 1, t0
+ storei t0, PayloadOffset[cfr, t1, 8]
+ loadis 8[PB, PC, 8], t1
+ storep t3, [cfr, t1, 8]
+ loadis 16[PB, PC, 8], t3
+ assertNotConstant(t3)
+ loadp [cfr, t3, 8], t3
+ loadp JSCell::m_structure[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:
+ bpeq Structure::m_prototype[t1], ValueNull, .opNextPnameSlow
+ loadp Structure::m_prototype[t1], t2
+ loadp JSCell::m_structure[t2], t1
+ bpneq t1, [t0], .opNextPnameSlow
+ addp 8, t0
+ btpnz [t0], .opNextPnameCheckPrototypeLoop
+.opNextPnameTarget:
+ dispatchInt(48[PB, PC, 8])
+
+.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 JIT throwing protocol calls for the cfr to be in t0. The throwing
+ # code must have known that we were throwing to the interpreter, and have
+ # set JSGlobalData::targetInterpreterPCForThrow.
+ move t0, cfr
+ loadp CodeBlock[cfr], PB
+ loadp CodeBlock::m_instructions[PB], PB
+ loadp JITStackFrame::globalData[sp], t3
+ loadp JSGlobalData::targetInterpreterPCForThrow[t3], PC
+ subp PB, PC
+ urshiftp 3, PC
+ loadp JSGlobalData::exception[t3], t0
+ storep 0, JSGlobalData::exception[t3]
+ loadis 8[PB, PC, 8], t2
+ storep t0, [cfr, t2, 8]
+ traceExecution()
+ dispatch(2)
+
+
+_llint_op_jsr:
+ traceExecution()
+ loadis 8[PB, PC, 8], t0
+ addi 3, PC, t1
+ storei t1, [cfr, t0, 8]
+ dispatchInt(16[PB, PC, 8])
+
+
+_llint_op_sret:
+ traceExecution()
+ loadis 8[PB, PC, 8], t0
+ loadi [cfr, t0, 8], PC
+ dispatch(0)
+
+
+_llint_op_end:
+ traceExecution()
+ checkSwitchToJITForEpilogue()
+ loadis 8[PB, PC, 8], t0
+ assertNotConstant(t0)
+ loadp [cfr, t0, 8], t0
+ doReturn()
+
+
+_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 JITStackFrame::globalData[sp], t1
+ loadp JSGlobalData::callFrameForThrow[t1], t0
+ jmp JSGlobalData::targetMachinePCForThrow[t1]
+
+
+_llint_throw_during_call_trampoline:
+ preserveReturnAddressAfterCall(t2)
+ loadp JITStackFrame::globalData[sp], t1
+ loadp JSGlobalData::callFrameForThrow[t1], t0
+ jmp JSGlobalData::targetMachinePCForThrow[t1]
+
+
+macro nativeCallTrampoline(executableOffsetToFunction)
+ storep 0, CodeBlock[cfr]
+ loadp CallerFrame[cfr], t0
+ loadp ScopeChain[t0], t1
+ storep t1, ScopeChain[cfr]
+ peek 0, t1
+ storep t1, ReturnPC[cfr]
+ move cfr, t5 # t5 = rdi
+ subp 16 - 8, sp
+ loadp Callee[cfr], t4 # t4 = rsi
+ loadp JSFunction::m_executable[t4], t1
+ move t0, cfr # Restore cfr to avoid loading from stack
+ call executableOffsetToFunction[t1]
+ addp 16 - 8, sp
+ loadp JITStackFrame::globalData + 8[sp], t3
+ btpnz JSGlobalData::exception[t3], .exception
+ ret
+.exception:
+ preserveReturnAddressAfterCall(t1)
+ callSlowPath(_llint_throw_from_native_call)
+ jmp _llint_throw_from_slow_path_trampoline
+end
+
diff --git a/Source/JavaScriptCore/offlineasm/armv7.rb b/Source/JavaScriptCore/offlineasm/armv7.rb
index eb8df6869..ed7db5618 100644
--- a/Source/JavaScriptCore/offlineasm/armv7.rb
+++ b/Source/JavaScriptCore/offlineasm/armv7.rb
@@ -33,29 +33,9 @@ class Node
end
class SpecialRegister < NoChildren
- def initialize(name)
- @name = name
- end
-
def armV7Operand
@name
end
-
- def address?
- false
- end
-
- def label?
- false
- end
-
- def immediate?
- false
- end
-
- def register?
- true
- end
end
ARMv7_EXTRA_GPRS = [SpecialRegister.new("r9"), SpecialRegister.new("r8"), SpecialRegister.new("r3")]
@@ -228,7 +208,7 @@ def armV7LowerShiftOps(list)
| node |
if node.is_a? Instruction
case node.opcode
- when "lshifti", "rshifti", "urshifti"
+ when "lshifti", "rshifti", "urshifti", "lshiftp", "rshiftp", "urshiftp"
if node.operands.size == 2
newList << Instruction.new(node.codeOrigin, node.opcode, [armV7SanitizeShift(node.operands[0], newList), node.operands[1]])
else
@@ -469,7 +449,7 @@ def armV7LowerMalformedImmediates(list)
else
newList << node.armV7LowerMalformedImmediatesRecurse(newList)
end
- when "muli"
+ when "muli", "mulp"
if node.operands[0].is_a? Immediate
tmp = Tmp.new(codeOrigin, :gpr)
newList << Instruction.new(node.codeOrigin, "move", [node.operands[0], tmp])
@@ -535,9 +515,9 @@ def armV7LowerMisplacedAddresses(list)
if node.is_a? Instruction
postInstructions = []
case node.opcode
- when "addi", "addp", "addis", "andi", "andp", "lshifti", "muli", "negi", "noti", "ori", "oris",
- "orp", "rshifti", "urshifti", "subi", "subp", "subis", "xori", "xorp", /^bi/, /^bp/, /^bti/,
- /^btp/, /^ci/, /^cp/, /^ti/
+ when "addi", "addp", "addis", "andi", "andp", "lshifti", "lshiftp", "muli", "mulp", "negi",
+ "negp", "noti", "ori", "oris", "orp", "rshifti", "urshifti", "rshiftp", "urshiftp", "subi",
+ "subp", "subis", "xori", "xorp", /^bi/, /^bp/, /^bti/, /^btp/, /^ci/, /^cp/, /^ti/
newList << Instruction.new(node.codeOrigin,
node.opcode,
armV7AsRegisters(newList, postInstructions, node.operands, "i"))
@@ -649,7 +629,7 @@ end
#
class Sequence
- def lowerARMv7
+ def getModifiedListARMv7
myList = @list
# Verify that we will only see instructions and labels.
@@ -673,10 +653,8 @@ class Sequence
myList = armV7LowerRegisterReuse(myList)
myList = assignRegistersToTemporaries(myList, :gpr, ARMv7_EXTRA_GPRS)
myList = assignRegistersToTemporaries(myList, :fpr, ARMv7_EXTRA_FPRS)
- myList.each {
- | node |
- node.lower("ARMv7")
- }
+
+ return myList
end
end
@@ -792,13 +770,13 @@ class Instruction
emitArmV7Compact("orrs", "orrs", operands)
when "xori", "xorp"
emitArmV7Compact("eors", "eor", operands)
- when "lshifti"
+ when "lshifti", "lshiftp"
emitArmV7Compact("lsls", "lsls", operands)
- when "rshifti"
+ when "rshifti", "rshiftp"
emitArmV7Compact("asrs", "asrs", operands)
- when "urshifti"
+ when "urshifti", "urshiftp"
emitArmV7Compact("lsrs", "lsrs", operands)
- when "muli"
+ when "muli", "mulp"
if operands.size == 2 or operands[0] == operands[2] or operands[1] == operands[2]
emitArmV7("muls", operands)
else
@@ -807,11 +785,11 @@ class Instruction
end
when "subi", "subp", "subis"
emitArmV7Compact("subs", "subs", operands)
- when "negi"
+ when "negi", "negp"
$asm.puts "rsbs #{operands[0].armV7Operand}, #{operands[0].armV7Operand}, \#0"
when "noti"
$asm.puts "mvns #{operands[0].armV7Operand}, #{operands[0].armV7Operand}"
- when "loadi", "loadp"
+ when "loadi", "loadis", "loadp"
$asm.puts "ldr #{armV7FlippedOperands(operands)}"
when "storei", "storep"
$asm.puts "str #{armV7Operands(operands)}"
diff --git a/Source/JavaScriptCore/offlineasm/asm.rb b/Source/JavaScriptCore/offlineasm/asm.rb
index a93a8c5dd..12bade022 100644
--- a/Source/JavaScriptCore/offlineasm/asm.rb
+++ b/Source/JavaScriptCore/offlineasm/asm.rb
@@ -128,11 +128,15 @@ outputFlnm = ARGV.shift
$stderr.puts "offlineasm: Parsing #{asmFile} and #{offsetsFile} and creating assembly file #{outputFlnm}."
-configurationList = offsetsAndConfigurationIndex(offsetsFile)
-inputData = IO::read(asmFile)
+begin
+ configurationList = offsetsAndConfigurationIndex(offsetsFile)
+rescue MissingMagicValuesException
+ $stderr.puts "offlineasm: No magic values found. Skipping assembly file generation assuming the classic interpreter is enabled."
+ exit 0
+end
inputHash =
- "// offlineasm input hash: " + Digest::SHA1.hexdigest(inputData) +
+ "// offlineasm input hash: " + parseHash(asmFile) +
" " + Digest::SHA1.hexdigest(configurationList.map{|v| (v[0] + [v[1]]).join(' ')}.join(' ')) +
" " + selfHash
@@ -154,7 +158,7 @@ File.open(outputFlnm, "w") {
$asm = Assembler.new($output)
- ast = parse(lex(inputData))
+ ast = parse(asmFile)
configurationList.each {
| configuration |
@@ -163,6 +167,7 @@ File.open(outputFlnm, "w") {
forSettings(computeSettingsCombinations(ast)[configIndex], ast) {
| concreteSettings, lowLevelAST, backend |
lowLevelAST = lowLevelAST.resolve(*buildOffsetsMap(lowLevelAST, offsetsList))
+ lowLevelAST.validate
emitCodeInConfiguration(concreteSettings, lowLevelAST, backend) {
$asm.inAsm {
lowLevelAST.lower(backend)
diff --git a/Source/JavaScriptCore/offlineasm/ast.rb b/Source/JavaScriptCore/offlineasm/ast.rb
index f67b0fc60..e555b5d98 100644
--- a/Source/JavaScriptCore/offlineasm/ast.rb
+++ b/Source/JavaScriptCore/offlineasm/ast.rb
@@ -57,7 +57,7 @@ class Node
end
def codeOriginString
- "line number #{@codeOrigin}"
+ @codeOrigin.to_s
end
def descendants
@@ -383,6 +383,157 @@ class NegImmediate < Node
end
end
+class OrImmediates < Node
+ attr_reader :left, :right
+
+ def initialize(codeOrigin, left, right)
+ super(codeOrigin)
+ @left = left
+ @right = right
+ end
+
+ def children
+ [@left, @right]
+ end
+
+ def mapChildren
+ OrImmediates.new(codeOrigin, (yield @left), (yield @right))
+ end
+
+ def dump
+ "(#{left.dump} | #{right.dump})"
+ end
+
+ def address?
+ false
+ end
+
+ def label?
+ false
+ end
+
+ def immediate?
+ true
+ end
+
+ def register?
+ false
+ end
+end
+
+class AndImmediates < Node
+ attr_reader :left, :right
+
+ def initialize(codeOrigin, left, right)
+ super(codeOrigin)
+ @left = left
+ @right = right
+ end
+
+ def children
+ [@left, @right]
+ end
+
+ def mapChildren
+ AndImmediates.new(codeOrigin, (yield @left), (yield @right))
+ end
+
+ def dump
+ "(#{left.dump} & #{right.dump})"
+ end
+
+ def address?
+ false
+ end
+
+ def label?
+ false
+ end
+
+ def immediate?
+ true
+ end
+
+ def register?
+ false
+ end
+end
+
+class XorImmediates < Node
+ attr_reader :left, :right
+
+ def initialize(codeOrigin, left, right)
+ super(codeOrigin)
+ @left = left
+ @right = right
+ end
+
+ def children
+ [@left, @right]
+ end
+
+ def mapChildren
+ XorImmediates.new(codeOrigin, (yield @left), (yield @right))
+ end
+
+ def dump
+ "(#{left.dump} ^ #{right.dump})"
+ end
+
+ def address?
+ false
+ end
+
+ def label?
+ false
+ end
+
+ def immediate?
+ true
+ end
+
+ def register?
+ false
+ end
+end
+
+class BitnotImmediate < Node
+ attr_reader :child
+
+ def initialize(codeOrigin, child)
+ super(codeOrigin)
+ @child = child
+ end
+
+ def children
+ [@child]
+ end
+
+ def mapChildren
+ BitnotImmediate.new(codeOrigin, (yield @child))
+ end
+
+ def dump
+ "(~#{@child.dump})"
+ end
+
+ def address?
+ false
+ end
+
+ def label?
+ false
+ end
+
+ def immediate?
+ true
+ end
+
+ def register?
+ false
+ end
+end
+
class RegisterID < NoChildren
attr_reader :name
@@ -459,6 +610,28 @@ class FPRegisterID < NoChildren
end
end
+class SpecialRegister < NoChildren
+ def initialize(name)
+ @name = name
+ end
+
+ def address?
+ false
+ end
+
+ def label?
+ false
+ end
+
+ def immediate?
+ false
+ end
+
+ def register?
+ true
+ end
+end
+
class Variable < NoChildren
attr_reader :name
@@ -479,6 +652,10 @@ class Variable < NoChildren
def dump
name
end
+
+ def inspect
+ "<variable #{name} at #{codeOriginString}>"
+ end
end
class Address < Node
@@ -757,6 +934,10 @@ class LabelReference < Node
def label?
true
end
+
+ def immediate?
+ false
+ end
end
class LocalLabelReference < NoChildren
@@ -790,6 +971,10 @@ class LocalLabelReference < NoChildren
def label?
true
end
+
+ def immediate?
+ false
+ end
end
class Sequence < Node
diff --git a/Source/JavaScriptCore/offlineasm/backends.rb b/Source/JavaScriptCore/offlineasm/backends.rb
index 2c65b517d..db7a1e218 100644
--- a/Source/JavaScriptCore/offlineasm/backends.rb
+++ b/Source/JavaScriptCore/offlineasm/backends.rb
@@ -28,6 +28,7 @@ require "x86"
BACKENDS =
[
"X86",
+ "X86_64",
"ARMv7"
]
@@ -39,6 +40,7 @@ BACKENDS =
WORKING_BACKENDS =
[
"X86",
+ "X86_64",
"ARMv7"
]
@@ -46,7 +48,12 @@ BACKEND_PATTERN = Regexp.new('\\A(' + BACKENDS.join(')|(') + ')\\Z')
class Node
def lower(name)
- send("lower" + name)
+ begin
+ $activeBackend = name
+ send("lower" + name)
+ rescue => e
+ raise "Got error #{e} at #{codeOriginString}"
+ end
end
end
@@ -83,7 +90,14 @@ end
class Sequence
def lower(name)
- if respond_to? "lower#{name}"
+ $activeBackend = name
+ if respond_to? "getModifiedList#{name}"
+ newList = send("getModifiedList#{name}")
+ newList.each {
+ | node |
+ node.lower(name)
+ }
+ elsif respond_to? "lower#{name}"
send("lower#{name}")
else
@list.each {
diff --git a/Source/JavaScriptCore/offlineasm/generate_offset_extractor.rb b/Source/JavaScriptCore/offlineasm/generate_offset_extractor.rb
index 8bdf4505d..b2a8c2c83 100644
--- a/Source/JavaScriptCore/offlineasm/generate_offset_extractor.rb
+++ b/Source/JavaScriptCore/offlineasm/generate_offset_extractor.rb
@@ -45,8 +45,7 @@ def emitMagicNumber
}
end
-inputData = IO::read(inputFlnm)
-inputHash = "// offlineasm input hash: #{Digest::SHA1.hexdigest(inputData)} #{selfHash}"
+inputHash = "// offlineasm input hash: #{parseHash(inputFlnm)} #{selfHash}"
if FileTest.exist? outputFlnm
File.open(outputFlnm, "r") {
@@ -59,7 +58,7 @@ if FileTest.exist? outputFlnm
}
end
-originalAST = parse(lex(inputData))
+originalAST = parse(inputFlnm)
#
# Optimize the AST to make configuration extraction faster. This reduces the AST to a form
diff --git a/Source/JavaScriptCore/offlineasm/instructions.rb b/Source/JavaScriptCore/offlineasm/instructions.rb
index 497b47371..cc7e0c6a5 100644
--- a/Source/JavaScriptCore/offlineasm/instructions.rb
+++ b/Source/JavaScriptCore/offlineasm/instructions.rb
@@ -30,15 +30,20 @@ MACRO_INSTRUCTIONS =
"addi",
"andi",
"lshifti",
+ "lshiftp",
"muli",
"negi",
+ "negp",
"noti",
"ori",
"rshifti",
"urshifti",
+ "rshiftp",
+ "urshiftp",
"subi",
"xori",
"loadi",
+ "loadis",
"loadb",
"loadbs",
"loadh",
@@ -56,6 +61,8 @@ MACRO_INSTRUCTIONS =
"ci2d",
"fii2d", # usage: fii2d <gpr with least significant bits>, <gpr with most significant bits>, <fpr>
"fd2ii", # usage: fd2ii <fpr>, <gpr with least significant bits>, <gpr with most significant bits>
+ "fp2d",
+ "fd2p",
"bdeq",
"bdneq",
"bdgt",
@@ -157,6 +164,7 @@ MACRO_INSTRUCTIONS =
"bplt",
"bplteq",
"addp",
+ "mulp",
"andp",
"orp",
"subp",
diff --git a/Source/JavaScriptCore/offlineasm/offsets.rb b/Source/JavaScriptCore/offlineasm/offsets.rb
index 21e1706d2..63af014bb 100644
--- a/Source/JavaScriptCore/offlineasm/offsets.rb
+++ b/Source/JavaScriptCore/offlineasm/offsets.rb
@@ -27,6 +27,16 @@ OFFSET_HEADER_MAGIC_NUMBERS = [ 0x9e43fd66, 0x4379bfba ]
OFFSET_MAGIC_NUMBERS = [ 0xec577ac7, 0x0ff5e755 ]
#
+# MissingMagicValuesException
+#
+# Thrown when magic values are missing from the binary.
+# This is usually an indication that the classic interpreter is enabled.
+#
+
+class MissingMagicValuesException < Exception
+end
+
+#
# offsetsList(ast)
# sizesList(ast)
#
@@ -142,7 +152,7 @@ def offsetsAndConfigurationIndex(file)
end
}
- raise unless result.length >= 1
+ raise MissingMagicValuesException unless result.length >= 1
raise if result.map{|v| v[1]}.uniq.size < result.map{|v| v[1]}.size
result
diff --git a/Source/JavaScriptCore/offlineasm/parser.rb b/Source/JavaScriptCore/offlineasm/parser.rb
index f0e4b0045..11863c724 100644
--- a/Source/JavaScriptCore/offlineasm/parser.rb
+++ b/Source/JavaScriptCore/offlineasm/parser.rb
@@ -23,7 +23,22 @@
require "ast"
require "instructions"
+require "pathname"
require "registers"
+require "self_hash"
+
+class CodeOrigin
+ attr_reader :fileName, :lineNumber
+
+ def initialize(fileName, lineNumber)
+ @fileName = fileName
+ @lineNumber = lineNumber
+ end
+
+ def to_s
+ "#{fileName}:#{lineNumber}"
+ end
+end
class Token
attr_reader :codeOrigin, :string
@@ -46,7 +61,7 @@ class Token
end
def to_s
- "#{@string.inspect} at line #{codeOrigin}"
+ "#{@string.inspect} at #{codeOrigin}"
end
def parseError(*comment)
@@ -62,7 +77,8 @@ end
# The lexer. Takes a string and returns an array of tokens.
#
-def lex(str)
+def lex(str, fileName)
+ fileName = Pathname.new(fileName)
result = []
lineNumber = 1
while not str.empty?
@@ -70,28 +86,28 @@ def lex(str)
when /\A\#([^\n]*)/
# comment, ignore
when /\A\n/
- result << Token.new(lineNumber, $&)
+ result << Token.new(CodeOrigin.new(fileName, lineNumber), $&)
lineNumber += 1
when /\A[a-zA-Z]([a-zA-Z0-9_]*)/
- result << Token.new(lineNumber, $&)
+ result << Token.new(CodeOrigin.new(fileName, lineNumber), $&)
when /\A\.([a-zA-Z0-9_]*)/
- result << Token.new(lineNumber, $&)
+ result << Token.new(CodeOrigin.new(fileName, lineNumber), $&)
when /\A_([a-zA-Z0-9_]*)/
- result << Token.new(lineNumber, $&)
+ result << Token.new(CodeOrigin.new(fileName, lineNumber), $&)
when /\A([ \t]+)/
# whitespace, ignore
when /\A0x([0-9a-fA-F]+)/
- result << Token.new(lineNumber, $&.hex.to_s)
+ result << Token.new(CodeOrigin.new(fileName, lineNumber), $&.hex.to_s)
when /\A0([0-7]+)/
- result << Token.new(lineNumber, $&.oct.to_s)
+ result << Token.new(CodeOrigin.new(fileName, lineNumber), $&.oct.to_s)
when /\A([0-9]+)/
- result << Token.new(lineNumber, $&)
+ result << Token.new(CodeOrigin.new(fileName, lineNumber), $&)
when /\A::/
- result << Token.new(lineNumber, $&)
- when /\A[:,\(\)\[\]=\+\-*]/
- result << Token.new(lineNumber, $&)
+ result << Token.new(CodeOrigin.new(fileName, lineNumber), $&)
+ when /\A[:,\(\)\[\]=\+\-~\|&^*]/
+ result << Token.new(CodeOrigin.new(fileName, lineNumber), $&)
else
- raise "Lexer error at line number #{lineNumber}, unexpected sequence #{str[0..20].inspect}"
+ raise "Lexer error at #{CodeOrigin.new(fileName, lineNumber).to_s}, unexpected sequence #{str[0..20].inspect}"
end
str = $~.post_match
end
@@ -111,7 +127,7 @@ def isInstruction(token)
end
def isKeyword(token)
- token =~ /\A((true)|(false)|(if)|(then)|(else)|(elsif)|(end)|(and)|(or)|(not)|(macro)|(const)|(sizeof)|(error))\Z/ or
+ token =~ /\A((true)|(false)|(if)|(then)|(else)|(elsif)|(end)|(and)|(or)|(not)|(macro)|(const)|(sizeof)|(error)|(include))\Z/ or
token =~ REGISTER_PATTERN or
token =~ INSTRUCTION_PATTERN
end
@@ -142,8 +158,8 @@ end
#
class Parser
- def initialize(tokens)
- @tokens = tokens
+ def initialize(data, fileName)
+ @tokens = lex(data, fileName)
@idx = 0
end
@@ -306,6 +322,9 @@ class Parser
if @tokens[@idx] == "-"
@idx += 1
NegImmediate.new(@tokens[@idx - 1].codeOrigin, parseExpressionAtom)
+ elsif @tokens[@idx] == "~"
+ @idx += 1
+ BitnotImmediate.new(@tokens[@idx - 1].codeOrigin, parseExpressionAtom)
elsif @tokens[@idx] == "("
@idx += 1
result = parseExpression
@@ -349,10 +368,10 @@ class Parser
end
def couldBeExpression
- @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 isVariable(@tokens[@idx]) or @tokens[@idx] == "("
end
- def parseExpression
+ def parseExpressionAdd
skipNewLine
result = parseExpressionMul
while @tokens[@idx] == "+" or @tokens[@idx] == "-"
@@ -369,6 +388,33 @@ class Parser
result
end
+ def parseExpressionAnd
+ skipNewLine
+ result = parseExpressionAdd
+ while @tokens[@idx] == "&"
+ @idx += 1
+ result = AndImmediates.new(@tokens[@idx - 1].codeOrigin, result, parseExpressionAdd)
+ end
+ result
+ end
+
+ def parseExpression
+ skipNewLine
+ result = parseExpressionAnd
+ while @tokens[@idx] == "|" or @tokens[@idx] == "^"
+ if @tokens[@idx] == "|"
+ @idx += 1
+ result = OrImmediates.new(@tokens[@idx - 1].codeOrigin, result, parseExpressionAnd)
+ elsif @tokens[@idx] == "^"
+ @idx += 1
+ result = XorImmediates.new(@tokens[@idx - 1].codeOrigin, result, parseExpressionAnd)
+ else
+ raise
+ end
+ end
+ result
+ end
+
def parseOperand(comment)
skipNewLine
if couldBeExpression
@@ -571,6 +617,14 @@ class Parser
list << LocalLabel.forName(codeOrigin, name)
end
@idx += 1
+ elsif @tokens[@idx] == "include"
+ @idx += 1
+ parseError unless isIdentifier(@tokens[@idx])
+ moduleName = @tokens[@idx].string
+ fileName = @tokens[@idx].codeOrigin.fileName.dirname + (moduleName + ".asm")
+ @idx += 1
+ $stderr.puts "offlineasm: Including file #{fileName}"
+ list << parse(fileName)
else
parseError "Expecting terminal #{final} #{comment}"
end
@@ -579,8 +633,16 @@ class Parser
end
end
-def parse(tokens)
- parser = Parser.new(tokens)
+def parseData(data, fileName)
+ parser = Parser.new(data, fileName)
parser.parseSequence(nil, "")
end
+def parse(fileName)
+ parseData(IO::read(fileName), fileName)
+end
+
+def parseHash(fileName)
+ dirHash(Pathname.new(fileName).dirname, /\.asm$/)
+end
+
diff --git a/Source/JavaScriptCore/offlineasm/registers.rb b/Source/JavaScriptCore/offlineasm/registers.rb
index 75fae4192..2c5a4ebf6 100644
--- a/Source/JavaScriptCore/offlineasm/registers.rb
+++ b/Source/JavaScriptCore/offlineasm/registers.rb
@@ -34,7 +34,13 @@ GPRS =
"r0",
"r1",
"sp",
- "lr"
+ "lr",
+
+ # 64-bit only registers:
+ "t5",
+ "t6", # r10
+ "csr1", # r14, tag type number register
+ "csr2" # r15, tag mask register
]
FPRS =
diff --git a/Source/JavaScriptCore/offlineasm/self_hash.rb b/Source/JavaScriptCore/offlineasm/self_hash.rb
index a7b51e112..2c300fccc 100644
--- a/Source/JavaScriptCore/offlineasm/self_hash.rb
+++ b/Source/JavaScriptCore/offlineasm/self_hash.rb
@@ -25,22 +25,33 @@ require "digest/sha1"
require "pathname"
#
-# selfHash -> SHA1 hexdigest
+# dirHash(directory, regexp) -> SHA1 hexdigest
#
-# Returns a hash of the offlineasm source code. This allows dependency
-# tracking for not just changes in input, but also changes in the assembler
-# itself.
+# Returns a hash of all files in the given directory that fit the given
+# pattern.
#
-def selfHash
+def dirHash(directory, regexp)
+ directory = Pathname.new(directory)
contents = ""
- myPath = Pathname.new(__FILE__).dirname
- Dir.foreach(myPath) {
+ Dir.foreach(directory) {
| entry |
- if entry =~ /\.rb$/
- contents += IO::read(myPath + entry)
+ if entry =~ regexp
+ contents += IO::read(directory + entry)
end
}
return Digest::SHA1.hexdigest(contents)
end
+#
+# selfHash -> SHA1 hexdigest
+#
+# Returns a hash of the offlineasm source code. This allows dependency
+# tracking for not just changes in input, but also changes in the assembler
+# itself.
+#
+
+def selfHash
+ dirHash(Pathname.new(__FILE__).dirname, /\.rb$/)
+end
+
diff --git a/Source/JavaScriptCore/offlineasm/settings.rb b/Source/JavaScriptCore/offlineasm/settings.rb
index 34598181c..b7daa7492 100644
--- a/Source/JavaScriptCore/offlineasm/settings.rb
+++ b/Source/JavaScriptCore/offlineasm/settings.rb
@@ -53,7 +53,7 @@ def computeSettingsCombinations(ast)
settingsCombinator(settingsCombinations, newMap, remaining[1..-1])
end
- settingsCombinator(settingsCombinations, {}, (ast.filter(Setting).uniq.collect{|v| v.name} + ["X86", "ARMv7"]).uniq)
+ settingsCombinator(settingsCombinations, {}, (ast.filter(Setting).uniq.collect{|v| v.name} + BACKENDS).uniq)
settingsCombinations
end
diff --git a/Source/JavaScriptCore/offlineasm/transform.rb b/Source/JavaScriptCore/offlineasm/transform.rb
index 5f5024d9e..86c72be67 100644
--- a/Source/JavaScriptCore/offlineasm/transform.rb
+++ b/Source/JavaScriptCore/offlineasm/transform.rb
@@ -328,6 +328,44 @@ class NegImmediate
end
end
+class OrImmediates
+ def fold
+ @left = @left.fold
+ @right = @right.fold
+ return self unless @left.is_a? Immediate
+ return self unless @right.is_a? Immediate
+ Immediate.new(codeOrigin, @left.value | @right.value)
+ end
+end
+
+class AndImmediates
+ def fold
+ @left = @left.fold
+ @right = @right.fold
+ return self unless @left.is_a? Immediate
+ return self unless @right.is_a? Immediate
+ Immediate.new(codeOrigin, @left.value & @right.value)
+ end
+end
+
+class XorImmediates
+ def fold
+ @left = @left.fold
+ @right = @right.fold
+ return self unless @left.is_a? Immediate
+ return self unless @right.is_a? Immediate
+ Immediate.new(codeOrigin, @left.value ^ @right.value)
+ end
+end
+
+class BitnotImmediate
+ def fold
+ @child = @child.fold
+ return self unless @child.is_a? Immediate
+ Immediate.new(codeOrigin, ~@child.value)
+ end
+end
+
#
# node.resolveAfterSettings(offsets, sizes)
#
@@ -340,3 +378,97 @@ class Node
end
end
+#
+# node.validate
+#
+# Checks that the node is ready for backend compilation.
+#
+
+class Node
+ def validate
+ raise "Unresolved #{dump} at #{codeOriginString}"
+ end
+
+ def validateChildren
+ children.each {
+ | node |
+ node.validate
+ }
+ end
+end
+
+class Sequence
+ def validate
+ validateChildren
+ end
+end
+
+class Immediate
+ def validate
+ end
+end
+
+class RegisterID
+ def validate
+ end
+end
+
+class FPRegisterID
+ def validate
+ end
+end
+
+class Address
+ def validate
+ validateChildren
+ end
+end
+
+class BaseIndex
+ def validate
+ validateChildren
+ end
+end
+
+class AbsoluteAddress
+ def validate
+ validateChildren
+ end
+end
+
+class Instruction
+ def validate
+ validateChildren
+ end
+end
+
+class Error
+ def validate
+ end
+end
+
+class Label
+ def validate
+ end
+end
+
+class LocalLabel
+ def validate
+ end
+end
+
+class LabelReference
+ def validate
+ end
+end
+
+class LocalLabelReference
+ def validate
+ end
+end
+
+class Skip
+ def validate
+ end
+end
+
diff --git a/Source/JavaScriptCore/offlineasm/x86.rb b/Source/JavaScriptCore/offlineasm/x86.rb
index b89f2d90c..4416ec909 100644
--- a/Source/JavaScriptCore/offlineasm/x86.rb
+++ b/Source/JavaScriptCore/offlineasm/x86.rb
@@ -1,4 +1,4 @@
-# Copyright (C) 2011 Apple Inc. All rights reserved.
+# 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
@@ -21,13 +21,48 @@
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGE.
+def isX64
+ case $activeBackend
+ when "X86"
+ false
+ when "X86_64"
+ true
+ else
+ raise "bad value for $activeBackend: #{$activeBackend}"
+ end
+end
+
+class SpecialRegister < NoChildren
+ def x86Operand(kind)
+ raise unless @name =~ /^r/
+ raise unless isX64
+ case kind
+ when :half
+ "%" + @name + "w"
+ when :int
+ "%" + @name + "d"
+ when :ptr
+ "%" + @name
+ else
+ raise
+ end
+ end
+ def x86CallOperand(kind)
+ "*#{x86Operand(kind)}"
+ end
+end
+
+X64_SCRATCH_REGISTER = SpecialRegister.new("r11")
+
class RegisterID
def supports8BitOnX86
case name
when "t0", "a0", "r0", "t1", "a1", "r1", "t2", "t3"
true
- when "t4", "cfr"
+ when "cfr", "ttnr", "tmr"
false
+ when "t4", "t5"
+ isX64
else
raise
end
@@ -43,6 +78,8 @@ class RegisterID
"%ax"
when :int
"%eax"
+ when :ptr
+ isX64 ? "%rax" : "%eax"
else
raise
end
@@ -54,6 +91,8 @@ class RegisterID
"%dx"
when :int
"%edx"
+ when :ptr
+ isX64 ? "%rdx" : "%edx"
else
raise
end
@@ -65,6 +104,8 @@ class RegisterID
"%cx"
when :int
"%ecx"
+ when :ptr
+ isX64 ? "%rcx" : "%ecx"
else
raise
end
@@ -76,6 +117,8 @@ class RegisterID
"%bx"
when :int
"%ebx"
+ when :ptr
+ isX64 ? "%rbx" : "%ebx"
else
raise
end
@@ -87,19 +130,36 @@ class RegisterID
"%si"
when :int
"%esi"
+ when :ptr
+ isX64 ? "%rsi" : "%esi"
else
raise
end
when "cfr"
- case kind
- when :byte
- "%dil"
- when :half
- "%di"
- when :int
- "%edi"
+ if isX64
+ case kind
+ when :half
+ "%r13w"
+ when :int
+ "%r13d"
+ when :ptr
+ "%r13"
+ else
+ raise
+ end
else
- raise
+ case kind
+ when :byte
+ "%dil"
+ when :half
+ "%di"
+ when :int
+ "%edi"
+ when :ptr
+ "%edi"
+ else
+ raise
+ end
end
when "sp"
case kind
@@ -109,9 +169,53 @@ class RegisterID
"%sp"
when :int
"%esp"
+ when :ptr
+ isX64 ? "%rsp" : "%esp"
else
raise
end
+ when "t5"
+ raise "Cannot use #{name} in 32-bit X86 at #{codeOriginString}" unless isX64
+ case kind
+ when :byte
+ "%dil"
+ when :half
+ "%di"
+ when :int
+ "%edi"
+ when :ptr
+ "%rdi"
+ end
+ when "t6"
+ raise "Cannot use #{name} in 32-bit X86 at #{codeOriginString}" unless isX64
+ case kind
+ when :half
+ "%r10w"
+ when :int
+ "%r10d"
+ when :ptr
+ "%r10"
+ end
+ when "csr1"
+ raise "Cannot use #{name} in 32-bit X86 at #{codeOriginString}" unless isX64
+ case kind
+ when :half
+ "%r14w"
+ when :int
+ "%r14d"
+ when :ptr
+ "%r14"
+ end
+ when "csr2"
+ raise "Cannot use #{name} in 32-bit X86 at #{codeOriginString}" unless isX64
+ case kind
+ when :half
+ "%r15w"
+ when :int
+ "%r15d"
+ when :ptr
+ "%r15"
+ end
else
raise "Bad register #{name} for X86 at #{codeOriginString}"
end
@@ -147,6 +251,13 @@ class FPRegisterID
end
class Immediate
+ def validX86Immediate?
+ if isX64
+ value >= -0x80000000 and value <= 0x7fffffff
+ else
+ true
+ end
+ end
def x86Operand(kind)
"$#{value}"
end
@@ -160,8 +271,11 @@ class Address
true
end
+ def x86AddressOperand(addressKind)
+ "#{offset.value}(#{base.x86Operand(addressKind)})"
+ end
def x86Operand(kind)
- "#{offset.value}(#{base.x86Operand(:int)})"
+ x86AddressOperand(:ptr)
end
def x86CallOperand(kind)
"*#{x86Operand(kind)}"
@@ -173,12 +287,16 @@ class BaseIndex
true
end
+ def x86AddressOperand(addressKind)
+ "#{offset.value}(#{base.x86Operand(addressKind)}, #{index.x86Operand(addressKind)}, #{scale})"
+ end
+
def x86Operand(kind)
- "#{offset.value}(#{base.x86Operand(:int)}, #{index.x86Operand(:int)}, #{scale})"
+ x86AddressOperand(:ptr)
end
def x86CallOperand(kind)
- "*#{x86operand(kind)}"
+ "*#{x86Operand(kind)}"
end
end
@@ -187,6 +305,10 @@ class AbsoluteAddress
true
end
+ def x86AddressOperand(addressKind)
+ "#{address.value}"
+ end
+
def x86Operand(kind)
"#{address.value}"
end
@@ -208,6 +330,47 @@ class LocalLabelReference
end
end
+class Sequence
+ def getModifiedListX86_64
+ newList = []
+
+ @list.each {
+ | node |
+ newNode = node
+ if node.is_a? Instruction
+ unless node.opcode == "move"
+ usedScratch = false
+ newOperands = node.operands.map {
+ | operand |
+ if operand.immediate? and not operand.validX86Immediate?
+ if usedScratch
+ raise "Attempt to use scratch register twice at #{operand.codeOriginString}"
+ end
+ newList << Instruction.new(operand.codeOrigin, "move", [operand, X64_SCRATCH_REGISTER])
+ usedScratch = true
+ X64_SCRATCH_REGISTER
+ else
+ operand
+ end
+ }
+ newNode = Instruction.new(node.codeOrigin, node.opcode, newOperands)
+ end
+ else
+ unless node.is_a? Label or
+ node.is_a? LocalLabel or
+ node.is_a? Skip
+ raise "Unexpected #{node.inspect} at #{node.codeOrigin}"
+ end
+ end
+ if newNode
+ newList << newNode
+ end
+ }
+
+ return newList
+ end
+end
+
class Instruction
def x86Operands(*kinds)
raise unless kinds.size == operands.size
@@ -227,6 +390,8 @@ class Instruction
"w"
when :int
"l"
+ when :ptr
+ isX64 ? "q" : "l"
when :double
"sd"
else
@@ -234,6 +399,23 @@ class Instruction
end
end
+ def x86Bytes(kind)
+ case kind
+ when :byte
+ 1
+ when :half
+ 2
+ when :int
+ 4
+ when :ptr
+ isX64 ? 8 : 4
+ when :double
+ 8
+ else
+ raise
+ end
+ end
+
def handleX86OpWithNumOperands(opcode, kind, numOperands)
if numOperands == 3
if operands[0] == operands[2]
@@ -257,9 +439,10 @@ class Instruction
if operands[0].is_a? Immediate or operands[0] == RegisterID.forName(nil, "t2")
$asm.puts "#{opcode} #{operands[0].x86Operand(:byte)}, #{operands[1].x86Operand(kind)}"
else
- $asm.puts "xchgl #{operands[0].x86Operand(:int)}, %ecx"
+ cx = RegisterID.forName(nil, "t2")
+ $asm.puts "xchg#{x86Suffix(:ptr)} #{operands[0].x86Operand(:ptr)}, #{cx.x86Operand(:ptr)}"
$asm.puts "#{opcode} %cl, #{operands[1].x86Operand(kind)}"
- $asm.puts "xchgl #{operands[0].x86Operand(:int)}, %ecx"
+ $asm.puts "xchg#{x86Suffix(:ptr)} #{operands[0].x86Operand(:ptr)}, #{cx.x86Operand(:ptr)}"
end
end
@@ -295,10 +478,11 @@ class Instruction
$asm.puts "#{setOpcode} #{operand.x86Operand(:byte)}"
$asm.puts "movzbl #{operand.x86Operand(:byte)}, #{operand.x86Operand(:int)}"
else
- $asm.puts "xchgl #{operand.x86Operand(:int)}, %eax"
+ ax = RegisterID.new(nil, "t0")
+ $asm.puts "xchg#{x86Suffix(:ptr)} #{operand.x86Operand(:ptr)}, #{ax.x86Operand(:ptr)}"
$asm.puts "#{setOpcode} %al"
$asm.puts "movzbl %al, %eax"
- $asm.puts "xchgl #{operand.x86Operand(:int)}, %eax"
+ $asm.puts "xchg#{x86Suffix(:ptr)} #{operand.x86Operand(:ptr)}, #{ax.x86Operand(:ptr)}"
end
end
@@ -354,8 +538,8 @@ class Instruction
def handleX86SubBranch(branchOpcode, kind)
if operands.size == 4 and operands[1] == operands[2]
- $asm.puts "negl #{operands[2].x86Operand(:int)}"
- $asm.puts "addl #{operands[0].x86Operand(:int)}, #{operands[2].x86Operand(:int)}"
+ $asm.puts "neg#{x86Suffix(kind)} #{operands[2].x86Operand(kind)}"
+ $asm.puts "add#{x86Suffix(kind)} #{operands[0].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
else
handleX86OpWithNumOperands("sub#{x86Suffix(kind)}", kind, operands.size - 1)
end
@@ -370,62 +554,120 @@ class Instruction
$asm.puts "#{branchOpcode} #{jumpTarget.asmLabel}"
end
- def lowerX86
- $asm.comment codeOriginString
- case opcode
- when "addi", "addp"
- if operands.size == 3 and operands[0].is_a? Immediate
- raise unless operands[1].is_a? RegisterID
- raise unless operands[2].is_a? RegisterID
- if operands[0].value == 0
- unless operands[1] == operands[2]
- $asm.puts "movl #{operands[1].x86Operand(:int)}, #{operands[2].x86Operand(:int)}"
- end
- else
- $asm.puts "leal #{operands[0].value}(#{operands[1].x86Operand(:int)}), #{operands[2].x86Operand(:int)}"
+ def handleX86Add(kind)
+ if operands.size == 3 and operands[0].is_a? Immediate
+ raise unless operands[1].is_a? RegisterID
+ raise unless operands[2].is_a? RegisterID
+ if operands[0].value == 0
+ unless operands[1] == operands[2]
+ $asm.puts "mov#{x86Suffix(kind)} #{operands[1].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
end
- elsif operands.size == 3 and operands[0].is_a? RegisterID
- raise unless operands[1].is_a? RegisterID
- raise unless operands[2].is_a? RegisterID
- $asm.puts "leal (#{operands[0].x86Operand(:int)}, #{operands[1].x86Operand(:int)}), #{operands[2].x86Operand(:int)}"
else
- unless Immediate.new(nil, 0) == operands[0]
- $asm.puts "addl #{x86Operands(:int, :int)}"
- end
+ $asm.puts "lea#{x86Suffix(kind)} #{operands[0].value}(#{operands[1].x86Operand(kind)}), #{operands[2].x86Operand(kind)}"
end
- when "andi", "andp"
+ elsif operands.size == 3 and operands[0].is_a? RegisterID
+ raise unless operands[1].is_a? RegisterID
+ raise unless operands[2].is_a? RegisterID
+ $asm.puts "lea#{x86Suffix(kind)} (#{operands[0].x86Operand(kind)}, #{operands[1].x86Operand(kind)}), #{operands[2].x86Operand(kind)}"
+ else
+ unless Immediate.new(nil, 0) == operands[0]
+ $asm.puts "add#{x86Suffix(kind)} #{x86Operands(kind, kind)}"
+ end
+ end
+ end
+
+ def handleX86Sub(kind)
+ if operands.size == 3 and operands[1] == operands[2]
+ $asm.puts "neg#{x86Suffix(kind)} #{operands[2].x86Operand(kind)}"
+ $asm.puts "add#{x86Suffix(kind)} #{operands[0].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
+ else
+ handleX86Op("sub#{x86Suffix(kind)}", kind)
+ end
+ end
+
+ def handleX86Mul(kind)
+ if operands.size == 3 and operands[0].is_a? Immediate
+ $asm.puts "imul#{x86Suffix(kind)} #{x86Operands(kind, kind, kind)}"
+ else
+ # FIXME: could do some peephole in case the left operand is immediate and it's
+ # a power of two.
+ handleX86Op("imul#{x86Suffix(kind)}", kind)
+ end
+ end
+
+ def handleMove
+ if Immediate.new(nil, 0) == operands[0] and operands[1].is_a? RegisterID
+ $asm.puts "xor#{x86Suffix(:ptr)} #{operands[1].x86Operand(:ptr)}, #{operands[1].x86Operand(:ptr)}"
+ elsif operands[0] != operands[1]
+ $asm.puts "mov#{x86Suffix(:ptr)} #{x86Operands(:ptr, :ptr)}"
+ end
+ end
+
+ def lowerX86
+ raise unless $activeBackend == "X86"
+ lowerX86Common
+ end
+
+ def lowerX86_64
+ raise unless $activeBackend == "X86_64"
+ lowerX86Common
+ end
+
+ def lowerX86Common
+ $asm.comment codeOriginString
+ case opcode
+ when "addi"
+ handleX86Add(:int)
+ when "addp"
+ handleX86Add(:ptr)
+ when "andi"
handleX86Op("andl", :int)
+ when "andp"
+ handleX86Op("and#{x86Suffix(:ptr)}", :ptr)
when "lshifti"
handleX86Shift("sall", :int)
+ when "lshiftp"
+ handleX86Shift("sal#{x86Suffix(:ptr)}", :ptr)
when "muli"
- if operands.size == 3 and operands[0].is_a? Immediate
- $asm.puts "imull #{x86Operands(:int, :int, :int)}"
- else
- # FIXME: could do some peephole in case the left operand is immediate and it's
- # a power of two.
- handleX86Op("imull", :int)
- end
+ handleX86Mul(:int)
+ when "mulp"
+ handleX86Mul(:ptr)
when "negi"
$asm.puts "negl #{x86Operands(:int)}"
+ when "negp"
+ $asm.puts "neg#{x86Suffix(:ptr)} #{x86Operands(:ptr)}"
when "noti"
$asm.puts "notl #{x86Operands(:int)}"
- when "ori", "orp"
+ when "ori"
handleX86Op("orl", :int)
+ when "orp"
+ handleX86Op("or#{x86Suffix(:ptr)}", :ptr)
when "rshifti"
handleX86Shift("sarl", :int)
+ when "rshiftp"
+ handleX86Shift("sar#{x86Suffix(:ptr)}", :ptr)
when "urshifti"
handleX86Shift("shrl", :int)
- when "subi", "subp"
- if operands.size == 3 and operands[1] == operands[2]
- $asm.puts "negl #{operands[2].x86Operand(:int)}"
- $asm.puts "addl #{operands[0].x86Operand(:int)}, #{operands[2].x86Operand(:int)}"
- else
- handleX86Op("subl", :int)
- end
- when "xori", "xorp"
+ when "urshiftp"
+ handleX86Shift("shr#{x86Suffix(:ptr)}", :ptr)
+ when "subi"
+ handleX86Sub(:int)
+ when "subp"
+ handleX86Sub(:ptr)
+ when "xori"
handleX86Op("xorl", :int)
- when "loadi", "storei", "loadp", "storep"
+ when "xorp"
+ handleX86Op("xor#{x86Suffix(:ptr)}", :ptr)
+ when "loadi", "storei"
$asm.puts "movl #{x86Operands(:int, :int)}"
+ when "loadis"
+ if isX64
+ $asm.puts "movslq #{x86Operands(:int, :ptr)}"
+ else
+ $asm.puts "movl #{x86Operands(:int, :int)}"
+ end
+ when "loadp", "storep"
+ $asm.puts "mov#{x86Suffix(:ptr)} #{x86Operands(:ptr, :ptr)}"
when "loadb"
$asm.puts "movzbl #{operands[0].x86Operand(:byte)}, #{operands[1].x86Operand(:int)}"
when "loadbs"
@@ -502,37 +744,65 @@ class Instruction
when "movdz"
$asm.puts "xorpd #{operands[0].x86Operand(:double)}, #{operands[0].x86Operand(:double)}"
when "pop"
- $asm.puts "pop #{operands[0].x86Operand(:int)}"
+ $asm.puts "pop #{operands[0].x86Operand(:ptr)}"
when "push"
- $asm.puts "push #{operands[0].x86Operand(:int)}"
- when "move", "sxi2p", "zxi2p"
- if Immediate.new(nil, 0) == operands[0] and operands[1].is_a? RegisterID
- $asm.puts "xorl #{operands[1].x86Operand(:int)}, #{operands[1].x86Operand(:int)}"
- elsif operands[0] != operands[1]
- $asm.puts "movl #{x86Operands(:int, :int)}"
+ $asm.puts "push #{operands[0].x86Operand(:ptr)}"
+ when "move"
+ handleMove
+ when "sxi2p"
+ if isX64
+ $asm.puts "movslq #{operands[0].x86Operand(:int)}, #{operands[1].x86Operand(:ptr)}"
+ else
+ handleMove
+ end
+ when "zxi2p"
+ if isX64
+ $asm.puts "movl #{operands[0].x86Operand(:int)}, #{operands[1].x86Operand(:int)}"
+ else
+ handleMove
end
when "nop"
$asm.puts "nop"
- when "bieq", "bpeq"
+ when "bieq"
handleX86IntBranch("je", :int)
- when "bineq", "bpneq"
+ when "bpeq"
+ handleX86IntBranch("je", :ptr)
+ when "bineq"
handleX86IntBranch("jne", :int)
- when "bia", "bpa"
+ when "bpneq"
+ handleX86IntBranch("jne", :ptr)
+ when "bia"
handleX86IntBranch("ja", :int)
- when "biaeq", "bpaeq"
+ when "bpa"
+ handleX86IntBranch("ja", :ptr)
+ when "biaeq"
handleX86IntBranch("jae", :int)
- when "bib", "bpb"
+ when "bpaeq"
+ handleX86IntBranch("jae", :ptr)
+ when "bib"
handleX86IntBranch("jb", :int)
- when "bibeq", "bpbeq"
+ when "bpb"
+ handleX86IntBranch("jb", :ptr)
+ when "bibeq"
handleX86IntBranch("jbe", :int)
- when "bigt", "bpgt"
+ when "bpbeq"
+ handleX86IntBranch("jbe", :ptr)
+ when "bigt"
handleX86IntBranch("jg", :int)
- when "bigteq", "bpgteq"
+ when "bpgt"
+ handleX86IntBranch("jg", :ptr)
+ when "bigteq"
handleX86IntBranch("jge", :int)
- when "bilt", "bplt"
+ when "bpgteq"
+ handleX86IntBranch("jge", :ptr)
+ when "bilt"
handleX86IntBranch("jl", :int)
- when "bilteq", "bplteq"
+ when "bplt"
+ handleX86IntBranch("jl", :ptr)
+ when "bilteq"
handleX86IntBranch("jle", :int)
+ when "bplteq"
+ handleX86IntBranch("jle", :ptr)
when "bbeq"
handleX86IntBranch("je", :byte)
when "bbneq"
@@ -553,14 +823,22 @@ class Instruction
handleX86IntBranch("jl", :byte)
when "bblteq"
handleX86IntBranch("jlteq", :byte)
- when "btio", "btpo"
+ when "btio"
handleX86BranchTest("jo", :int)
- when "btis", "btps"
+ when "btpo"
+ handleX86BranchTest("jo", :ptr)
+ when "btis"
handleX86BranchTest("js", :int)
- when "btiz", "btpz"
+ when "btps"
+ handleX86BranchTest("js", :ptr)
+ when "btiz"
handleX86BranchTest("jz", :int)
- when "btinz", "btpnz"
+ when "btpz"
+ handleX86BranchTest("jz", :ptr)
+ when "btinz"
handleX86BranchTest("jnz", :int)
+ when "btpnz"
+ handleX86BranchTest("jnz", :ptr)
when "btbo"
handleX86BranchTest("jo", :byte)
when "btbs"
@@ -570,15 +848,23 @@ class Instruction
when "btbnz"
handleX86BranchTest("jnz", :byte)
when "jmp"
- $asm.puts "jmp #{operands[0].x86CallOperand(:int)}"
- when "baddio", "baddpo"
+ $asm.puts "jmp #{operands[0].x86CallOperand(:ptr)}"
+ when "baddio"
handleX86OpBranch("addl", "jo", :int)
- when "baddis", "baddps"
+ when "baddpo"
+ handleX86OpBranch("add#{x86Suffix(:ptr)}", "jo", :ptr)
+ when "baddis"
handleX86OpBranch("addl", "js", :int)
- when "baddiz", "baddpz"
+ when "baddps"
+ handleX86OpBranch("add#{x86Suffix(:ptr)}", "js", :ptr)
+ when "baddiz"
handleX86OpBranch("addl", "jz", :int)
- when "baddinz", "baddpnz"
+ when "baddpz"
+ handleX86OpBranch("add#{x86Suffix(:ptr)}", "jz", :ptr)
+ when "baddinz"
handleX86OpBranch("addl", "jnz", :int)
+ when "baddpnz"
+ handleX86OpBranch("add#{x86Suffix(:ptr)}", "jnz", :ptr)
when "bsubio"
handleX86SubBranch("jo", :int)
when "bsubis"
@@ -606,29 +892,49 @@ class Instruction
when "break"
$asm.puts "int $3"
when "call"
- $asm.puts "call #{operands[0].x86CallOperand(:int)}"
+ $asm.puts "call #{operands[0].x86CallOperand(:ptr)}"
when "ret"
$asm.puts "ret"
- when "cieq", "cpeq"
+ when "cieq"
handleX86IntCompareSet("sete", :int)
- when "cineq", "cpneq"
+ when "cpeq"
+ handleX86IntCompareSet("sete", :ptr)
+ when "cineq"
handleX86IntCompareSet("setne", :int)
- when "cia", "cpa"
+ when "cpneq"
+ handleX86IntCompareSet("setne", :ptr)
+ when "cia"
handleX86IntCompareSet("seta", :int)
- when "ciaeq", "cpaeq"
+ when "cpa"
+ handleX86IntCompareSet("seta", :ptr)
+ when "ciaeq"
handleX86IntCompareSet("setae", :int)
- when "cib", "cpb"
+ when "cpaeq"
+ handleX86IntCompareSet("setae", :ptr)
+ when "cib"
handleX86IntCompareSet("setb", :int)
- when "cibeq", "cpbeq"
+ when "cpb"
+ handleX86IntCompareSet("setb", :ptr)
+ when "cibeq"
handleX86IntCompareSet("setbe", :int)
- when "cigt", "cpgt"
+ when "cpbeq"
+ handleX86IntCompareSet("setbe", :ptr)
+ when "cigt"
handleX86IntCompareSet("setg", :int)
- when "cigteq", "cpgteq"
+ when "cpgt"
+ handleX86IntCompareSet("setg", :ptr)
+ when "cigteq"
handleX86IntCompareSet("setge", :int)
- when "cilt", "cplt"
+ when "cpgteq"
+ handleX86IntCompareSet("setge", :ptr)
+ when "cilt"
handleX86IntCompareSet("setl", :int)
- when "cilteq", "cplteq"
+ when "cplt"
+ handleX86IntCompareSet("setl", :ptr)
+ when "cilteq"
handleX86IntCompareSet("setle", :int)
+ when "cplteq"
+ handleX86IntCompareSet("setle", :ptr)
when "tio"
handleX86SetTest("seto", :int)
when "tis"
@@ -646,9 +952,11 @@ class Instruction
when "tbnz"
handleX86SetTest("setnz", :byte)
when "peek"
- $asm.puts "movl #{operands[0].value * 4}(%esp), #{operands[1].x86Operand(:int)}"
+ sp = RegisterID.new(nil, "sp")
+ $asm.puts "mov#{x86Suffix(:ptr)} #{operands[0].value * x86Bytes(:ptr)}(#{sp.x86Operand(:ptr)}), #{operands[1].x86Operand(:ptr)}"
when "poke"
- $asm.puts "movl #{operands[0].x86Operand(:int)}, #{operands[1].value * 4}(%esp)"
+ sp = RegisterID.new(nil, "sp")
+ $asm.puts "mov#{x86Suffix(:ptr)} #{operands[0].x86Operand(:ptr)}, #{operands[1].value * x86Bytes(:ptr)}(#{sp.x86Operand(:ptr)})"
when "cdqi"
$asm.puts "cdq"
when "idivi"
@@ -663,6 +971,10 @@ class Instruction
$asm.puts "movsd #{operands[0].x86Operand(:double)}, %xmm7"
$asm.puts "psrlq $32, %xmm7"
$asm.puts "movsd %xmm7, #{operands[2].x86Operand(:int)}"
+ when "fp2d"
+ $asm.puts "movd #{operands[0].x86Operand(:ptr)}, #{operands[1].x86Operand(:double)}"
+ when "fd2p"
+ $asm.puts "movd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:ptr)}"
when "bo"
$asm.puts "jo #{operands[0].asmLabel}"
when "bs"
@@ -671,8 +983,10 @@ class Instruction
$asm.puts "jz #{operands[0].asmLabel}"
when "bnz"
$asm.puts "jnz #{operands[0].asmLabel}"
- when "leai", "leap"
- $asm.puts "leal #{operands[0].x86Operand(:int)}, #{operands[1].x86Operand(:int)}"
+ when "leai"
+ $asm.puts "leal #{operands[0].x86AddressOperand(:int)}, #{operands[1].x86Operand(:int)}"
+ when "leap"
+ $asm.puts "lea#{x86Suffix(:ptr)} #{operands[0].x86AddressOperand(:ptr)}, #{operands[1].x86Operand(:ptr)}"
else
raise "Bad opcode: #{opcode}"
end
diff --git a/Source/JavaScriptCore/parser/ASTBuilder.h b/Source/JavaScriptCore/parser/ASTBuilder.h
index b8718709b..a173cc10f 100644
--- a/Source/JavaScriptCore/parser/ASTBuilder.h
+++ b/Source/JavaScriptCore/parser/ASTBuilder.h
@@ -77,7 +77,6 @@ public:
: m_globalData(globalData)
, m_sourceCode(sourceCode)
, m_scope(globalData)
- , m_evalCount(0)
{
}
@@ -119,7 +118,6 @@ public:
ParserArenaData<DeclarationStacks::VarStack>* varDeclarations() { return m_scope.m_varDeclarations; }
ParserArenaData<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); }
@@ -152,17 +150,8 @@ public:
incConstants();
return new (m_globalData) VoidNode(lineNumber, expr);
}
- ExpressionNode* thisExpr(int lineNumber)
- {
- usesThis();
- return new (m_globalData) ThisNode(lineNumber);
- }
- ExpressionNode* createResolve(int lineNumber, const Identifier* ident, int start)
- {
- if (m_globalData->propertyNames->arguments == *ident)
- usesArguments();
- return new (m_globalData) ResolveNode(lineNumber, *ident, start);
- }
+ ExpressionNode* thisExpr(int lineNumber) { return new (m_globalData) ThisNode(lineNumber); }
+ ExpressionNode* createResolve(int lineNumber, const Identifier* ident, int start) { return new (m_globalData) ResolveNode(lineNumber, *ident, start); }
ExpressionNode* createObjectLiteral(int lineNumber) { return new (m_globalData) ObjectLiteralNode(lineNumber); }
ExpressionNode* createObjectLiteral(int lineNumber, PropertyListNode* properties) { return new (m_globalData) ObjectLiteralNode(lineNumber, properties); }
@@ -263,9 +252,9 @@ public:
return result;
}
- FunctionBodyNode* createFunctionBody(int lineNumber, bool inStrictContext)
+ FunctionBodyNode* createFunctionBody(int lineNumber, ScopeFlags scopeFlags)
{
- return FunctionBodyNode::create(m_globalData, lineNumber, inStrictContext);
+ return FunctionBodyNode::create(m_globalData, lineNumber, scopeFlags);
}
template <bool> PropertyNode* createGetterOrSetterProperty(int lineNumber, PropertyNode::Type type, const Identifier* name, ParameterNode* params, FunctionBodyNode* body, int openBracePos, int closeBracePos, int bodyStartLine, int bodyEndLine)
@@ -276,6 +265,11 @@ public:
return new (m_globalData) PropertyNode(m_globalData, *name, new (m_globalData) FuncExprNode(lineNumber, m_globalData->propertyNames->nullIdentifier, body, m_sourceCode->subExpression(openBracePos, closeBracePos, bodyStartLine), params), type);
}
+ template <bool> PropertyNode* createGetterOrSetterProperty(JSGlobalData*, int lineNumber, PropertyNode::Type type, double name, ParameterNode* params, FunctionBodyNode* body, int openBracePos, int closeBracePos, int bodyStartLine, int bodyEndLine)
+ {
+ body->setLoc(bodyStartLine, bodyEndLine);
+ return new (m_globalData) PropertyNode(m_globalData, name, new (m_globalData) FuncExprNode(lineNumber, m_globalData->propertyNames->nullIdentifier, body, m_sourceCode->subExpression(openBracePos, closeBracePos, bodyStartLine), params), type);
+ }
ArgumentsNode* createArguments() { return new (m_globalData) ArgumentsNode(); }
ArgumentsNode* createArguments(ArgumentListNode* args) { return new (m_globalData) ArgumentsNode(args); }
@@ -307,8 +301,6 @@ public:
StatementNode* createFuncDeclStatement(int lineNumber, const Identifier* name, FunctionBodyNode* body, ParameterNode* parameters, int openBracePos, int closeBracePos, int bodyStartLine, int bodyEndLine)
{
FuncDeclNode* decl = new (m_globalData) FuncDeclNode(lineNumber, *name, body, m_sourceCode->subExpression(openBracePos, closeBracePos, bodyStartLine), parameters);
- if (*name == m_globalData->propertyNames->arguments)
- usesArguments();
m_scope.m_funcDeclarations->data.append(decl->body());
body->setLoc(bodyStartLine, bodyEndLine);
return decl;
@@ -421,8 +413,6 @@ public:
StatementNode* createTryStatement(int lineNumber, StatementNode* tryBlock, const Identifier* ident, StatementNode* catchBlock, StatementNode* finallyBlock, int startLine, int endLine)
{
TryNode* result = new (m_globalData) TryNode(lineNumber, tryBlock, *ident, catchBlock, finallyBlock);
- if (catchBlock)
- usesCatch();
result->setLoc(startLine, endLine);
return result;
}
@@ -458,7 +448,6 @@ public:
StatementNode* createWithStatement(int lineNumber, ExpressionNode* expr, StatementNode* statement, int start, int end, int startLine, int endLine)
{
- usesWith();
WithNode* result = new (m_globalData) WithNode(lineNumber, expr, statement, end, end - start);
result->setLoc(startLine, endLine);
return result;
@@ -501,8 +490,6 @@ public:
void addVar(const Identifier* ident, int attrs)
{
- if (m_globalData->propertyNames->arguments == *ident)
- usesArguments();
m_scope.m_varDeclarations->data.append(std::make_pair(ident, attrs));
}
@@ -517,8 +504,6 @@ public:
return new (m_globalData) CommaNode(lineNumber, list, init);
}
- int evalCount() const { return m_evalCount; }
-
void appendBinaryExpressionInfo(int& operandStackDepth, ExpressionNode* current, int exprStart, int lhs, int rhs, bool hasAssignments)
{
operandStackDepth++;
@@ -605,13 +590,11 @@ private:
Scope(JSGlobalData* globalData)
: m_varDeclarations(new (globalData) ParserArenaData<DeclarationStacks::VarStack>)
, m_funcDeclarations(new (globalData) ParserArenaData<DeclarationStacks::FunctionStack>)
- , m_features(0)
, m_numConstants(0)
{
}
ParserArenaData<DeclarationStacks::VarStack>* m_varDeclarations;
ParserArenaData<DeclarationStacks::FunctionStack>* m_funcDeclarations;
- int m_features;
int m_numConstants;
};
@@ -621,15 +604,6 @@ private:
}
void incConstants() { m_scope.m_numConstants++; }
- void usesThis() { m_scope.m_features |= ThisFeature; }
- void usesCatch() { m_scope.m_features |= CatchFeature; }
- void usesArguments() { m_scope.m_features |= ArgumentsFeature; }
- void usesWith() { m_scope.m_features |= WithFeature; }
- void usesEval()
- {
- m_evalCount++;
- m_scope.m_features |= EvalFeature;
- }
ExpressionNode* createNumber(int lineNumber, double d)
{
return new (m_globalData) NumberNode(lineNumber, d);
@@ -642,7 +616,6 @@ private:
Vector<AssignmentInfo, 10> m_assignmentInfoStack;
Vector<pair<int, int>, 10> m_binaryOperatorStack;
Vector<pair<int, int>, 10> m_unaryTokenStack;
- int m_evalCount;
};
ExpressionNode* ASTBuilder::makeTypeOfNode(int lineNumber, ExpressionNode* expr)
@@ -792,10 +765,8 @@ ExpressionNode* ASTBuilder::makeFunctionCallNode(int lineNumber, ExpressionNode*
if (func->isResolveNode()) {
ResolveNode* resolve = static_cast<ResolveNode*>(func);
const Identifier& identifier = resolve->identifier();
- if (identifier == m_globalData->propertyNames->eval) {
- usesEval();
+ if (identifier == m_globalData->propertyNames->eval)
return new (m_globalData) EvalFunctionCallNode(lineNumber, args, divot, divot - start, end - divot);
- }
return new (m_globalData) FunctionCallResolveNode(lineNumber, identifier, args, divot, divot - start, end - divot);
}
if (func->isBracketAccessorNode()) {
diff --git a/Source/JavaScriptCore/parser/Lexer.cpp b/Source/JavaScriptCore/parser/Lexer.cpp
index 015c1509d..8d50afc54 100644
--- a/Source/JavaScriptCore/parser/Lexer.cpp
+++ b/Source/JavaScriptCore/parser/Lexer.cpp
@@ -31,7 +31,7 @@
#include "Identifier.h"
#include "NodeInfo.h"
#include "Nodes.h"
-#include "dtoa.h"
+#include <wtf/dtoa.h>
#include <ctype.h>
#include <limits.h>
#include <string.h>
@@ -95,8 +95,8 @@ enum CharacterType {
CharacterWhiteSpace,
};
-// 128 ASCII codes
-static const unsigned short typesOfASCIICharacters[128] = {
+// 256 Latin-1 codes
+static const unsigned short typesOfLatin1Characters[256] = {
/* 0 - Null */ CharacterInvalid,
/* 1 - Start of Heading */ CharacterInvalid,
/* 2 - Start of Text */ CharacterInvalid,
@@ -225,6 +225,134 @@ static const unsigned short typesOfASCIICharacters[128] = {
/* 125 - } */ CharacterCloseBrace,
/* 126 - ~ */ CharacterTilde,
/* 127 - Delete */ CharacterInvalid,
+/* 128 - Cc category */ CharacterInvalid,
+/* 129 - Cc category */ CharacterInvalid,
+/* 130 - Cc category */ CharacterInvalid,
+/* 131 - Cc category */ CharacterInvalid,
+/* 132 - Cc category */ CharacterInvalid,
+/* 133 - Cc category */ CharacterInvalid,
+/* 134 - Cc category */ CharacterInvalid,
+/* 135 - Cc category */ CharacterInvalid,
+/* 136 - Cc category */ CharacterInvalid,
+/* 137 - Cc category */ CharacterInvalid,
+/* 138 - Cc category */ CharacterInvalid,
+/* 139 - Cc category */ CharacterInvalid,
+/* 140 - Cc category */ CharacterInvalid,
+/* 141 - Cc category */ CharacterInvalid,
+/* 142 - Cc category */ CharacterInvalid,
+/* 143 - Cc category */ CharacterInvalid,
+/* 144 - Cc category */ CharacterInvalid,
+/* 145 - Cc category */ CharacterInvalid,
+/* 146 - Cc category */ CharacterInvalid,
+/* 147 - Cc category */ CharacterInvalid,
+/* 148 - Cc category */ CharacterInvalid,
+/* 149 - Cc category */ CharacterInvalid,
+/* 150 - Cc category */ CharacterInvalid,
+/* 151 - Cc category */ CharacterInvalid,
+/* 152 - Cc category */ CharacterInvalid,
+/* 153 - Cc category */ CharacterInvalid,
+/* 154 - Cc category */ CharacterInvalid,
+/* 155 - Cc category */ CharacterInvalid,
+/* 156 - Cc category */ CharacterInvalid,
+/* 157 - Cc category */ CharacterInvalid,
+/* 158 - Cc category */ CharacterInvalid,
+/* 159 - Cc category */ CharacterInvalid,
+/* 160 - Zs category (nbsp) */ CharacterWhiteSpace,
+/* 161 - Po category */ CharacterInvalid,
+/* 162 - Sc category */ CharacterInvalid,
+/* 163 - Sc category */ CharacterInvalid,
+/* 164 - Sc category */ CharacterInvalid,
+/* 165 - Sc category */ CharacterInvalid,
+/* 166 - So category */ CharacterInvalid,
+/* 167 - So category */ CharacterInvalid,
+/* 168 - Sk category */ CharacterInvalid,
+/* 169 - So category */ CharacterInvalid,
+/* 170 - Ll category */ CharacterIdentifierStart,
+/* 171 - Pi category */ CharacterInvalid,
+/* 172 - Sm category */ CharacterInvalid,
+/* 173 - Cf category */ CharacterInvalid,
+/* 174 - So category */ CharacterInvalid,
+/* 175 - Sk category */ CharacterInvalid,
+/* 176 - So category */ CharacterInvalid,
+/* 177 - Sm category */ CharacterInvalid,
+/* 178 - No category */ CharacterInvalid,
+/* 179 - No category */ CharacterInvalid,
+/* 180 - Sk category */ CharacterInvalid,
+/* 181 - Ll category */ CharacterIdentifierStart,
+/* 182 - So category */ CharacterInvalid,
+/* 183 - Po category */ CharacterInvalid,
+/* 184 - Sk category */ CharacterInvalid,
+/* 185 - No category */ CharacterInvalid,
+/* 186 - Ll category */ CharacterIdentifierStart,
+/* 187 - Pf category */ CharacterInvalid,
+/* 188 - No category */ CharacterInvalid,
+/* 189 - No category */ CharacterInvalid,
+/* 190 - No category */ CharacterInvalid,
+/* 191 - Po category */ CharacterInvalid,
+/* 192 - Lu category */ CharacterIdentifierStart,
+/* 193 - Lu category */ CharacterIdentifierStart,
+/* 194 - Lu category */ CharacterIdentifierStart,
+/* 195 - Lu category */ CharacterIdentifierStart,
+/* 196 - Lu category */ CharacterIdentifierStart,
+/* 197 - Lu category */ CharacterIdentifierStart,
+/* 198 - Lu category */ CharacterIdentifierStart,
+/* 199 - Lu category */ CharacterIdentifierStart,
+/* 200 - Lu category */ CharacterIdentifierStart,
+/* 201 - Lu category */ CharacterIdentifierStart,
+/* 202 - Lu category */ CharacterIdentifierStart,
+/* 203 - Lu category */ CharacterIdentifierStart,
+/* 204 - Lu category */ CharacterIdentifierStart,
+/* 205 - Lu category */ CharacterIdentifierStart,
+/* 206 - Lu category */ CharacterIdentifierStart,
+/* 207 - Lu category */ CharacterIdentifierStart,
+/* 208 - Lu category */ CharacterIdentifierStart,
+/* 209 - Lu category */ CharacterIdentifierStart,
+/* 210 - Lu category */ CharacterIdentifierStart,
+/* 211 - Lu category */ CharacterIdentifierStart,
+/* 212 - Lu category */ CharacterIdentifierStart,
+/* 213 - Lu category */ CharacterIdentifierStart,
+/* 214 - Lu category */ CharacterIdentifierStart,
+/* 215 - Sm category */ CharacterInvalid,
+/* 216 - Lu category */ CharacterIdentifierStart,
+/* 217 - Lu category */ CharacterIdentifierStart,
+/* 218 - Lu category */ CharacterIdentifierStart,
+/* 219 - Lu category */ CharacterIdentifierStart,
+/* 220 - Lu category */ CharacterIdentifierStart,
+/* 221 - Lu category */ CharacterIdentifierStart,
+/* 222 - Lu category */ CharacterIdentifierStart,
+/* 223 - Ll category */ CharacterIdentifierStart,
+/* 224 - Ll category */ CharacterIdentifierStart,
+/* 225 - Ll category */ CharacterIdentifierStart,
+/* 226 - Ll category */ CharacterIdentifierStart,
+/* 227 - Ll category */ CharacterIdentifierStart,
+/* 228 - Ll category */ CharacterIdentifierStart,
+/* 229 - Ll category */ CharacterIdentifierStart,
+/* 230 - Ll category */ CharacterIdentifierStart,
+/* 231 - Ll category */ CharacterIdentifierStart,
+/* 232 - Ll category */ CharacterIdentifierStart,
+/* 233 - Ll category */ CharacterIdentifierStart,
+/* 234 - Ll category */ CharacterIdentifierStart,
+/* 235 - Ll category */ CharacterIdentifierStart,
+/* 236 - Ll category */ CharacterIdentifierStart,
+/* 237 - Ll category */ CharacterIdentifierStart,
+/* 238 - Ll category */ CharacterIdentifierStart,
+/* 239 - Ll category */ CharacterIdentifierStart,
+/* 240 - Ll category */ CharacterIdentifierStart,
+/* 241 - Ll category */ CharacterIdentifierStart,
+/* 242 - Ll category */ CharacterIdentifierStart,
+/* 243 - Ll category */ CharacterIdentifierStart,
+/* 244 - Ll category */ CharacterIdentifierStart,
+/* 245 - Ll category */ CharacterIdentifierStart,
+/* 246 - Ll category */ CharacterIdentifierStart,
+/* 247 - Sm category */ CharacterInvalid,
+/* 248 - Ll category */ CharacterIdentifierStart,
+/* 249 - Ll category */ CharacterIdentifierStart,
+/* 250 - Ll category */ CharacterIdentifierStart,
+/* 251 - Ll category */ CharacterIdentifierStart,
+/* 252 - Ll category */ CharacterIdentifierStart,
+/* 253 - Ll category */ CharacterIdentifierStart,
+/* 254 - Ll category */ CharacterIdentifierStart,
+/* 255 - Ll category */ CharacterIdentifierStart
};
template <typename T>
@@ -350,7 +478,7 @@ int Lexer<T>::getUnicodeCharacter()
template <typename T>
void Lexer<T>::shiftLineTerminator()
{
- ASSERT(isLineTerminator(m_current));
+ ASSERT(isLineTerminator(static_cast<T>(m_current)));
int m_prev = m_current;
shift();
@@ -368,28 +496,48 @@ ALWAYS_INLINE bool Lexer<T>::lastTokenWasRestrKeyword() const
return m_lastToken == CONTINUE || m_lastToken == BREAK || m_lastToken == RETURN || m_lastToken == THROW;
}
-static NEVER_INLINE bool isNonASCIIIdentStart(int c)
+static NEVER_INLINE bool isNonLatin1IdentStart(int c)
{
return category(c) & (Letter_Uppercase | Letter_Lowercase | Letter_Titlecase | Letter_Modifier | Letter_Other);
}
-static inline bool isIdentStart(int c)
+static ALWAYS_INLINE bool isLatin1(LChar)
{
- return isASCII(c) ? typesOfASCIICharacters[c] == CharacterIdentifierStart : isNonASCIIIdentStart(c);
+ return true;
+}
+
+static ALWAYS_INLINE bool isLatin1(UChar c)
+{
+ return c < 256;
}
-static NEVER_INLINE bool isNonASCIIIdentPart(int c)
+static inline bool isIdentStart(LChar c)
+{
+ return typesOfLatin1Characters[c] == CharacterIdentifierStart;
+}
+
+static inline bool isIdentStart(UChar c)
+{
+ return isLatin1(c) ? isIdentStart(static_cast<LChar>(c)) : isNonLatin1IdentStart(c);
+}
+
+static NEVER_INLINE bool isNonLatin1IdentPart(int c)
{
return (category(c) & (Letter_Uppercase | Letter_Lowercase | Letter_Titlecase | Letter_Modifier | Letter_Other
| Mark_NonSpacing | Mark_SpacingCombining | Number_DecimalDigit | Punctuation_Connector)) || c == 0x200C || c == 0x200D;
}
-static ALWAYS_INLINE bool isIdentPart(int c)
+static ALWAYS_INLINE bool isIdentPart(LChar c)
{
// Character types are divided into two groups depending on whether they can be part of an
// identifier or not. Those whose type value is less or equal than CharacterNumber can be
// part of an identifier. (See the CharacterType definition for more details.)
- return isASCII(c) ? typesOfASCIICharacters[c] <= CharacterNumber : isNonASCIIIdentPart(c);
+ return typesOfLatin1Characters[c] <= CharacterNumber;
+}
+
+static ALWAYS_INLINE bool isIdentPart(UChar c)
+{
+ return isLatin1(c) ? isIdentPart(static_cast<LChar>(c)) : isNonLatin1IdentPart(c);
}
static inline int singleEscape(int c)
@@ -499,7 +647,7 @@ template <>
const LChar* identifierStart = currentCharacter();
- while (isIdentPart(m_current))
+ while (m_current != -1 && isIdentPart(static_cast<LChar>(m_current)))
shift();
if (UNLIKELY(m_current == '\\')) {
@@ -550,7 +698,7 @@ template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType Lexer<UChar>::p
UChar orAllChars = 0;
- while (isIdentPart(m_current)) {
+ while (m_current != -1 && isIdentPart(static_cast<UChar>(m_current))) {
orAllChars |= m_current;
shift();
}
@@ -604,7 +752,7 @@ template <bool shouldCreateIdentifier> JSTokenType Lexer<T>::parseIdentifierSlow
bool bufferRequired = false;
while (true) {
- if (LIKELY(isIdentPart(m_current))) {
+ if (LIKELY(m_current != -1 && isIdentPart(static_cast<T>(m_current)))) {
shift();
continue;
}
@@ -622,10 +770,11 @@ template <bool shouldCreateIdentifier> JSTokenType Lexer<T>::parseIdentifierSlow
int character = getUnicodeCharacter();
if (UNLIKELY(character == -1))
return ERRORTOK;
- if (UNLIKELY(m_buffer16.size() ? !isIdentPart(character) : !isIdentStart(character)))
+ UChar ucharacter = static_cast<UChar>(character);
+ if (UNLIKELY(m_buffer16.size() ? !isIdentPart(ucharacter) : !isIdentStart(ucharacter)))
return ERRORTOK;
if (shouldCreateIdentifier)
- record16(character);
+ record16(ucharacter);
identifierStart = currentCharacter();
}
@@ -692,14 +841,15 @@ template <bool shouldBuildStrings> ALWAYS_INLINE bool Lexer<T>::parseString(JSTo
shiftLineTerminator();
else if (m_current == 'x') {
shift();
- if (isASCIIHexDigit(m_current) && isASCIIHexDigit(peek(1))) {
- int prev = m_current;
- shift();
- if (shouldBuildStrings)
- record8(convertHex(prev, m_current));
- shift();
- } else if (shouldBuildStrings)
- record8('x');
+ if (!isASCIIHexDigit(m_current) || !isASCIIHexDigit(peek(1))) {
+ m_lexErrorMessage = "\\x can only be followed by a hex character sequence";
+ return false;
+ }
+ int prev = m_current;
+ shift();
+ if (shouldBuildStrings)
+ record8(convertHex(prev, m_current));
+ shift();
} else {
setOffset(startingOffset);
setLineNumber(startingLineNumber);
@@ -752,18 +902,19 @@ template <bool shouldBuildStrings> bool Lexer<T>::parseStringSlowCase(JSTokenDat
if (shouldBuildStrings)
record16(escape);
shift();
- } else if (UNLIKELY(isLineTerminator(m_current)))
+ } else if (UNLIKELY(isLineTerminator(static_cast<T>(m_current))))
shiftLineTerminator();
else if (m_current == 'x') {
shift();
- if (isASCIIHexDigit(m_current) && isASCIIHexDigit(peek(1))) {
- int prev = m_current;
- shift();
- if (shouldBuildStrings)
- record16(convertHex(prev, m_current));
- shift();
- } else if (shouldBuildStrings)
- record16('x');
+ if (!isASCIIHexDigit(m_current) || !isASCIIHexDigit(peek(1))) {
+ m_lexErrorMessage = "\\x can only be followed by a hex character sequence";
+ return false;
+ }
+ int prev = m_current;
+ shift();
+ if (shouldBuildStrings)
+ record16(convertHex(prev, m_current));
+ shift();
} else if (m_current == 'u') {
shift();
int character = getUnicodeCharacter();
@@ -824,7 +975,7 @@ template <bool shouldBuildStrings> bool Lexer<T>::parseStringSlowCase(JSTokenDat
// as possible, and lets through all common ASCII characters.
if (UNLIKELY(((static_cast<unsigned>(m_current) - 0xE) & 0x2000))) {
// New-line or end of input is not allowed
- if (UNLIKELY(isLineTerminator(m_current)) || UNLIKELY(m_current == -1)) {
+ if (UNLIKELY(m_current == -1) || UNLIKELY(isLineTerminator(static_cast<T>(m_current)))) {
m_lexErrorMessage = "Unexpected EOF";
return false;
}
@@ -1004,7 +1155,7 @@ ALWAYS_INLINE bool Lexer<T>::parseMultilineComment()
if (UNLIKELY(m_current == -1))
return false;
- if (isLineTerminator(m_current)) {
+ if (isLineTerminator(static_cast<T>(m_current))) {
shiftLineTerminator();
m_terminator = true;
} else
@@ -1033,7 +1184,7 @@ JSTokenType Lexer<T>::lex(JSTokenData* tokenData, JSTokenInfo* tokenInfo, unsign
m_terminator = false;
start:
- while (isWhiteSpace(m_current))
+ while (m_current != -1 && isWhiteSpace(static_cast<T>(m_current)))
shift();
int startOffset = currentOffset();
@@ -1044,11 +1195,11 @@ start:
m_delimited = false;
CharacterType type;
- if (LIKELY(isASCII(m_current)))
- type = static_cast<CharacterType>(typesOfASCIICharacters[m_current]);
- else if (isNonASCIIIdentStart(m_current))
+ if (LIKELY(isLatin1(static_cast<T>(m_current))))
+ type = static_cast<CharacterType>(typesOfLatin1Characters[m_current]);
+ else if (isNonLatin1IdentStart(m_current))
type = CharacterIdentifierStart;
- else if (isLineTerminator(m_current))
+ else if (isLineTerminator(static_cast<T>(m_current)))
type = CharacterLineTerminator;
else
type = CharacterInvalid;
@@ -1335,7 +1486,7 @@ inNumberAfterDecimalPoint:
}
// No identifiers allowed directly after numeric literal, e.g. "3in" is bad.
- if (UNLIKELY(isIdentStart(m_current))) {
+ if (UNLIKELY(m_current != -1 && isIdentStart(static_cast<T>(m_current)))) {
m_lexErrorMessage = "At least one digit must occur after a decimal point";
goto returnError;
}
@@ -1355,7 +1506,7 @@ inNumberAfterDecimalPoint:
token = STRING;
break;
case CharacterIdentifierStart:
- ASSERT(isIdentStart(m_current));
+ ASSERT(isIdentStart(static_cast<T>(m_current)));
// Fall through into CharacterBackSlash.
case CharacterBackSlash:
if (lexerFlags & LexexFlagsDontBuildKeywords)
@@ -1364,7 +1515,7 @@ inNumberAfterDecimalPoint:
token = parseIdentifier<true>(tokenData, lexerFlags, strictMode);
break;
case CharacterLineTerminator:
- ASSERT(isLineTerminator(m_current));
+ ASSERT(isLineTerminator(static_cast<T>(m_current)));
shiftLineTerminator();
m_atLineStart = true;
m_terminator = true;
@@ -1382,7 +1533,7 @@ inNumberAfterDecimalPoint:
goto returnToken;
inSingleLineComment:
- while (!isLineTerminator(m_current)) {
+ while (!isLineTerminator(static_cast<T>(m_current))) {
if (UNLIKELY(m_current == -1))
return EOFTOK;
shift();
@@ -1430,7 +1581,7 @@ bool Lexer<T>::scanRegExp(const Identifier*& pattern, const Identifier*& flags,
while (true) {
int current = m_current;
- if (isLineTerminator(current) || current == -1) {
+ if (isLineTerminator(static_cast<T>(current)) || current == -1) {
m_buffer16.resize(0);
return false;
}
@@ -1463,7 +1614,7 @@ bool Lexer<T>::scanRegExp(const Identifier*& pattern, const Identifier*& flags,
pattern = makeIdentifier(m_buffer16.data(), m_buffer16.size());
m_buffer16.resize(0);
- while (isIdentPart(m_current)) {
+ while (m_current != -1 && isIdentPart(static_cast<T>(m_current))) {
record16(m_current);
shift();
}
@@ -1483,7 +1634,7 @@ bool Lexer<T>::skipRegExp()
while (true) {
int current = m_current;
- if (isLineTerminator(current) || current == -1)
+ if (isLineTerminator(static_cast<T>(current)) || current == -1)
return false;
shift();
@@ -1509,7 +1660,7 @@ bool Lexer<T>::skipRegExp()
}
}
- while (isIdentPart(m_current))
+ while (m_current != -1 && isIdentPart(static_cast<T>(m_current)))
shift();
return true;
diff --git a/Source/JavaScriptCore/parser/Lexer.h b/Source/JavaScriptCore/parser/Lexer.h
index 6fe0c9a1c..81558fa96 100644
--- a/Source/JavaScriptCore/parser/Lexer.h
+++ b/Source/JavaScriptCore/parser/Lexer.h
@@ -79,8 +79,8 @@ public:
~Lexer();
// Character manipulation functions.
- static bool isWhiteSpace(int character);
- static bool isLineTerminator(int character);
+ static bool isWhiteSpace(T character);
+ static bool isLineTerminator(T character);
static unsigned char convertHex(int c1, int c2);
static UChar convertUnicode(int c1, int c2, int c3, int c4);
@@ -191,14 +191,26 @@ private:
JSGlobalData* m_globalData;
};
-template <typename T>
-ALWAYS_INLINE bool Lexer<T>::isWhiteSpace(int ch)
+template <>
+ALWAYS_INLINE bool Lexer<LChar>::isWhiteSpace(LChar ch)
{
- return isASCII(ch) ? (ch == ' ' || ch == '\t' || ch == 0xB || ch == 0xC) : (WTF::Unicode::isSeparatorSpace(ch) || ch == 0xFEFF);
+ return ch == ' ' || ch == '\t' || ch == 0xB || ch == 0xC || ch == 0xA0;
}
-template <typename T>
-ALWAYS_INLINE bool Lexer<T>::isLineTerminator(int ch)
+template <>
+ALWAYS_INLINE bool Lexer<UChar>::isWhiteSpace(UChar ch)
+{
+ return (ch < 256) ? Lexer<LChar>::isWhiteSpace(static_cast<LChar>(ch)) : (WTF::Unicode::isSeparatorSpace(ch) || ch == 0xFEFF);
+}
+
+template <>
+ALWAYS_INLINE bool Lexer<LChar>::isLineTerminator(LChar ch)
+{
+ return ch == '\r' || ch == '\n';
+}
+
+template <>
+ALWAYS_INLINE bool Lexer<UChar>::isLineTerminator(UChar ch)
{
return ch == '\r' || ch == '\n' || (ch & ~1) == 0x2028;
}
diff --git a/Source/JavaScriptCore/parser/NodeConstructors.h b/Source/JavaScriptCore/parser/NodeConstructors.h
index eea3f575c..e496d2342 100644
--- a/Source/JavaScriptCore/parser/NodeConstructors.h
+++ b/Source/JavaScriptCore/parser/NodeConstructors.h
@@ -417,12 +417,13 @@ namespace JSC {
}
inline NegateNode::NegateNode(int lineNumber, ExpressionNode* expr)
- : UnaryOpNode(lineNumber, ResultType::numberTypeCanReuse(), expr, op_negate)
+ : UnaryOpNode(lineNumber, ResultType::numberType(), expr, op_negate)
{
}
inline BitwiseNotNode::BitwiseNotNode(int lineNumber, ExpressionNode* expr)
- : UnaryOpNode(lineNumber, ResultType::forBitOp(), expr, op_bitnot)
+ : ExpressionNode(lineNumber, ResultType::forBitOp())
+ , m_expr(expr)
{
}
@@ -450,18 +451,18 @@ namespace JSC {
}
inline MultNode::MultNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
- : BinaryOpNode(lineNumber, ResultType::numberTypeCanReuse(), expr1, expr2, op_mul, rightHasAssignments)
+ : BinaryOpNode(lineNumber, ResultType::numberType(), expr1, expr2, op_mul, rightHasAssignments)
{
}
inline DivNode::DivNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
- : BinaryOpNode(lineNumber, ResultType::numberTypeCanReuse(), expr1, expr2, op_div, rightHasAssignments)
+ : BinaryOpNode(lineNumber, ResultType::numberType(), expr1, expr2, op_div, rightHasAssignments)
{
}
inline ModNode::ModNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
- : BinaryOpNode(lineNumber, ResultType::numberTypeCanReuse(), expr1, expr2, op_mod, rightHasAssignments)
+ : BinaryOpNode(lineNumber, ResultType::numberType(), expr1, expr2, op_mod, rightHasAssignments)
{
}
@@ -471,7 +472,7 @@ namespace JSC {
}
inline SubNode::SubNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
- : BinaryOpNode(lineNumber, ResultType::numberTypeCanReuse(), expr1, expr2, op_sub, rightHasAssignments)
+ : BinaryOpNode(lineNumber, ResultType::numberType(), expr1, expr2, op_sub, rightHasAssignments)
{
}
@@ -486,7 +487,7 @@ namespace JSC {
}
inline UnsignedRightShiftNode::UnsignedRightShiftNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
- : BinaryOpNode(lineNumber, ResultType::numberTypeCanReuse(), expr1, expr2, op_urshift, rightHasAssignments)
+ : BinaryOpNode(lineNumber, ResultType::numberType(), expr1, expr2, op_urshift, rightHasAssignments)
{
}
diff --git a/Source/JavaScriptCore/parser/NodeInfo.h b/Source/JavaScriptCore/parser/NodeInfo.h
index 4853aec42..e0d4ffec4 100644
--- a/Source/JavaScriptCore/parser/NodeInfo.h
+++ b/Source/JavaScriptCore/parser/NodeInfo.h
@@ -26,7 +26,7 @@ namespace JSC {
template <typename T> struct NodeInfo {
T m_node;
- CodeFeatures m_features;
+ ScopeFlags m_scopeFlags;
int m_numConstants;
};
@@ -44,7 +44,7 @@ namespace JSC {
T m_node;
ParserArenaData<DeclarationStacks::VarStack>* m_varDeclarations;
ParserArenaData<DeclarationStacks::FunctionStack>* m_funcDeclarations;
- CodeFeatures m_features;
+ ScopeFlags m_scopeFlags;
int m_numConstants;
};
diff --git a/Source/JavaScriptCore/parser/Nodes.cpp b/Source/JavaScriptCore/parser/Nodes.cpp
index 8ad474e54..75c848bce 100644
--- a/Source/JavaScriptCore/parser/Nodes.cpp
+++ b/Source/JavaScriptCore/parser/Nodes.cpp
@@ -73,75 +73,70 @@ StatementNode* SourceElements::singleStatement() const
return size == 1 ? m_statements[0] : 0;
}
-// -----------------------------ScopeNodeData ---------------------------
-
-ScopeNodeData::ScopeNodeData(ParserArena& arena, SourceElements* statements, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, int numConstants)
- : m_numConstants(numConstants)
- , m_statements(statements)
-{
- m_arena.swap(arena);
- if (varStack)
- m_varStack.swap(*varStack);
- if (funcStack)
- m_functionStack.swap(*funcStack);
- m_capturedVariables.swap(capturedVariables);
-}
-
// ------------------------------ ScopeNode -----------------------------
-ScopeNode::ScopeNode(JSGlobalData* globalData, int lineNumber, bool inStrictContext)
+ScopeNode::ScopeNode(JSGlobalData* globalData, int lineNumber, ScopeFlags scopeFlags)
: StatementNode(lineNumber)
, ParserArenaRefCounted(globalData)
- , m_features(inStrictContext ? StrictModeFeature : NoFeatures)
+ , m_scopeFlags(scopeFlags)
+ , m_numConstants(0)
+ , m_statements(0)
{
}
-ScopeNode::ScopeNode(JSGlobalData* globalData, int lineNumber, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, CodeFeatures features, int numConstants)
+ScopeNode::ScopeNode(JSGlobalData* globalData, int lineNumber, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, ScopeFlags scopeFlags, int numConstants)
: StatementNode(lineNumber)
, ParserArenaRefCounted(globalData)
- , m_data(adoptPtr(new ScopeNodeData(*globalData->parserArena, children, varStack, funcStack, capturedVariables, numConstants)))
- , m_features(features)
+ , m_scopeFlags(scopeFlags)
, m_source(source)
+ , m_numConstants(numConstants)
+ , m_statements(children)
{
+ m_arena.swap(*globalData->parserArena);
+ if (varStack)
+ m_varStack.swap(*varStack);
+ if (funcStack)
+ m_functionStack.swap(*funcStack);
+ m_capturedVariables.swap(capturedVariables);
}
StatementNode* ScopeNode::singleStatement() const
{
- return m_data->m_statements ? m_data->m_statements->singleStatement() : 0;
+ return m_statements ? m_statements->singleStatement() : 0;
}
// ------------------------------ ProgramNode -----------------------------
-inline ProgramNode::ProgramNode(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
- : ScopeNode(globalData, lineNumber, source, children, varStack, funcStack, capturedVariables, features, numConstants)
+inline ProgramNode::ProgramNode(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, ScopeFlags scopeFlags, int numConstants)
+ : ScopeNode(globalData, lineNumber, source, children, varStack, funcStack, capturedVariables, scopeFlags, numConstants)
{
}
-PassRefPtr<ProgramNode> ProgramNode::create(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
+PassRefPtr<ProgramNode> ProgramNode::create(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, ScopeFlags scopeFlags, int numConstants)
{
- RefPtr<ProgramNode> node = new ProgramNode(globalData, lineNumber, children, varStack, funcStack, capturedVariables, source, features, numConstants);
+ RefPtr<ProgramNode> node = new ProgramNode(globalData, lineNumber, children, varStack, funcStack, capturedVariables, source, scopeFlags, numConstants);
- ASSERT(node->data()->m_arena.last() == node);
- node->data()->m_arena.removeLast();
- ASSERT(!node->data()->m_arena.contains(node.get()));
+ ASSERT(node->m_arena.last() == node);
+ node->m_arena.removeLast();
+ ASSERT(!node->m_arena.contains(node.get()));
return node.release();
}
// ------------------------------ EvalNode -----------------------------
-inline EvalNode::EvalNode(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
- : ScopeNode(globalData, lineNumber, source, children, varStack, funcStack, capturedVariables, features, numConstants)
+inline EvalNode::EvalNode(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, ScopeFlags scopeFlags, int numConstants)
+ : ScopeNode(globalData, lineNumber, source, children, varStack, funcStack, capturedVariables, scopeFlags, numConstants)
{
}
-PassRefPtr<EvalNode> EvalNode::create(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
+PassRefPtr<EvalNode> EvalNode::create(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, ScopeFlags scopeFlags, int numConstants)
{
- RefPtr<EvalNode> node = new EvalNode(globalData, lineNumber, children, varStack, funcStack, capturedVariables, source, features, numConstants);
+ RefPtr<EvalNode> node = new EvalNode(globalData, lineNumber, children, varStack, funcStack, capturedVariables, source, scopeFlags, numConstants);
- ASSERT(node->data()->m_arena.last() == node);
- node->data()->m_arena.removeLast();
- ASSERT(!node->data()->m_arena.contains(node.get()));
+ ASSERT(node->m_arena.last() == node);
+ node->m_arena.removeLast();
+ ASSERT(!node->m_arena.contains(node.get()));
return node.release();
}
@@ -154,13 +149,13 @@ FunctionParameters::FunctionParameters(ParameterNode* firstParameter)
append(parameter->ident());
}
-inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, int lineNumber, bool inStrictContext)
- : ScopeNode(globalData, lineNumber, inStrictContext)
+inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, int lineNumber, ScopeFlags scopeFlags)
+ : ScopeNode(globalData, lineNumber, scopeFlags)
{
}
-inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
- : ScopeNode(globalData, lineNumber, sourceCode, children, varStack, funcStack, capturedVariables, features, numConstants)
+inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, ScopeFlags scopeFlags, int numConstants)
+ : ScopeNode(globalData, lineNumber, sourceCode, children, varStack, funcStack, capturedVariables, scopeFlags, numConstants)
{
}
@@ -177,18 +172,18 @@ void FunctionBodyNode::finishParsing(PassRefPtr<FunctionParameters> parameters,
m_ident = ident;
}
-FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, int lineNumber, bool inStrictContext)
+FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, int lineNumber, ScopeFlags scopeFlags)
{
- return new FunctionBodyNode(globalData, lineNumber, inStrictContext);
+ return new FunctionBodyNode(globalData, lineNumber, scopeFlags);
}
-PassRefPtr<FunctionBodyNode> FunctionBodyNode::create(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
+PassRefPtr<FunctionBodyNode> FunctionBodyNode::create(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, ScopeFlags scopeFlags, int numConstants)
{
- RefPtr<FunctionBodyNode> node = new FunctionBodyNode(globalData, lineNumber, children, varStack, funcStack, capturedVariables, sourceCode, features, numConstants);
+ RefPtr<FunctionBodyNode> node = new FunctionBodyNode(globalData, lineNumber, children, varStack, funcStack, capturedVariables, sourceCode, scopeFlags, numConstants);
- ASSERT(node->data()->m_arena.last() == node);
- node->data()->m_arena.removeLast();
- ASSERT(!node->data()->m_arena.contains(node.get()));
+ ASSERT(node->m_arena.last() == node);
+ node->m_arena.removeLast();
+ ASSERT(!node->m_arena.contains(node.get()));
return node.release();
}
diff --git a/Source/JavaScriptCore/parser/Nodes.h b/Source/JavaScriptCore/parser/Nodes.h
index 0373766b5..f752b91e9 100644
--- a/Source/JavaScriptCore/parser/Nodes.h
+++ b/Source/JavaScriptCore/parser/Nodes.h
@@ -47,19 +47,31 @@ namespace JSC {
class ScopeChainNode;
class ScopeNode;
- typedef unsigned CodeFeatures;
-
- const CodeFeatures NoFeatures = 0;
- const CodeFeatures EvalFeature = 1 << 0;
- const CodeFeatures ArgumentsFeature = 1 << 1;
- const CodeFeatures WithFeature = 1 << 2;
- const CodeFeatures CatchFeature = 1 << 3;
- const CodeFeatures ThisFeature = 1 << 4;
- const CodeFeatures StrictModeFeature = 1 << 5;
- const CodeFeatures ShadowsArgumentsFeature = 1 << 6;
+ typedef unsigned short ScopeFlags;
+
+ const ScopeFlags NoScopeFlags = 0;
+
+ // Some scope flags propagate down the parse tree from parent scopes, like
+ // strict mode. They are modal to an entire set of nested scopes.
+ const ScopeFlags StrictModeFlag = 1 << 0;
+ const ScopeFlags FunctionModeFlag = 1 << 1;
+ const ScopeFlags AllScopeModeFlags = StrictModeFlag | FunctionModeFlag;
+
+ // Some scope flags refer only to a specific scope, and don't propagate down
+ // or up.
+ const ScopeFlags BlockScopeFlag = 1 << 4;
+ const ScopeFlags AllScopeKindFlags = BlockScopeFlag;
+
+ // Other flags reflect uses within nested scopes, and so propagate up
+ // from the leaves.
+ const ScopeFlags UsesEvalFlag = 1 << 8;
+ const ScopeFlags UsesArgumentsFlag = 1 << 9;
+ const ScopeFlags UsesWithFlag = 1 << 10;
+ const ScopeFlags UsesCatchFlag = 1 << 11;
+ const ScopeFlags UsesThisFlag = 1 << 12;
+ const ScopeFlags ShadowsArgumentsFlag = 1 << 13;
+ const ScopeFlags AllScopeUsesFlags = UsesEvalFlag | UsesArgumentsFlag | UsesWithFlag | UsesCatchFlag | UsesThisFlag | ShadowsArgumentsFlag;
- const CodeFeatures AllFeatures = EvalFeature | ArgumentsFeature | WithFeature | CatchFeature | ThisFeature | StrictModeFeature | ShadowsArgumentsFeature;
-
enum Operator {
OpEqual,
OpPlusEq,
@@ -793,11 +805,20 @@ namespace JSC {
NegateNode(int, ExpressionNode*);
};
- class BitwiseNotNode : public UnaryOpNode {
+ class BitwiseNotNode : public ExpressionNode {
public:
BitwiseNotNode(int, ExpressionNode*);
- };
+ protected:
+ ExpressionNode* expr() { return m_expr; }
+ const ExpressionNode* expr() const { return m_expr; }
+
+ private:
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+ ExpressionNode* m_expr;
+ };
+
class LogicalNotNode : public UnaryOpNode {
public:
LogicalNotNode(int, ExpressionNode*);
@@ -1369,62 +1390,53 @@ namespace JSC {
ParameterNode* m_next;
};
- struct ScopeNodeData {
- WTF_MAKE_FAST_ALLOCATED;
+ class ScopeNode : public StatementNode, public ParserArenaRefCounted {
public:
typedef DeclarationStacks::VarStack VarStack;
typedef DeclarationStacks::FunctionStack FunctionStack;
- ScopeNodeData(ParserArena&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, int numConstants);
+ ScopeNode(JSGlobalData*, int, ScopeFlags);
+ ScopeNode(JSGlobalData*, int, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, ScopeFlags, int numConstants);
- ParserArena m_arena;
- VarStack m_varStack;
- FunctionStack m_functionStack;
- int m_numConstants;
- SourceElements* m_statements;
- IdentifierSet m_capturedVariables;
- };
+ using ParserArenaRefCounted::operator new;
- class ScopeNode : public StatementNode, public ParserArenaRefCounted {
- public:
- typedef DeclarationStacks::VarStack VarStack;
- typedef DeclarationStacks::FunctionStack FunctionStack;
+ void destroyData()
+ {
+ m_arena.reset();
+ m_varStack.clear();
+ m_functionStack.clear();
+ m_statements = 0;
+ m_capturedVariables.clear();
+ }
- ScopeNode(JSGlobalData*, int, bool inStrictContext);
- ScopeNode(JSGlobalData*, int, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, CodeFeatures, int numConstants);
+ bool hasCapturedVariables() const { return !!m_capturedVariables.size(); }
+ size_t capturedVariableCount() const { return m_capturedVariables.size(); }
+ bool captures(const Identifier& ident) { return m_capturedVariables.contains(ident.impl()); }
- using ParserArenaRefCounted::operator new;
+ void addScopeFlags(ScopeFlags scopeFlags) { m_scopeFlags |= scopeFlags; }
+ ScopeFlags scopeFlags() const { return m_scopeFlags; }
- ScopeNodeData* data() const { return m_data.get(); }
- void destroyData() { m_data.clear(); }
+ bool isStrictMode() const { return m_scopeFlags & StrictModeFlag; }
+ bool usesEval() const { return m_scopeFlags & UsesEvalFlag; }
+ bool usesArguments() const { return (m_scopeFlags & UsesArgumentsFlag) && !(m_scopeFlags & ShadowsArgumentsFlag); }
+ void setUsesArguments() { m_scopeFlags |= UsesArgumentsFlag; }
+ bool usesThis() const { return m_scopeFlags & UsesThisFlag; }
+
+ bool needsActivationForMoreThanVariables() const { return m_scopeFlags & (UsesEvalFlag | UsesWithFlag | UsesCatchFlag); }
+ bool needsActivation() const { return hasCapturedVariables() || needsActivationForMoreThanVariables(); }
const SourceCode& source() const { return m_source; }
const UString& sourceURL() const { return m_source.provider()->url(); }
intptr_t sourceID() const { return m_source.provider()->asID(); }
- void setFeatures(CodeFeatures features) { m_features = features; }
- CodeFeatures features() { return m_features; }
-
- bool usesEval() const { return m_features & EvalFeature; }
- bool usesArguments() const { return (m_features & ArgumentsFeature) && !(m_features & ShadowsArgumentsFeature); }
- bool isStrictMode() const { return m_features & StrictModeFeature; }
- void setUsesArguments() { m_features |= ArgumentsFeature; }
- bool usesThis() const { return m_features & ThisFeature; }
- bool needsActivationForMoreThanVariables() const { ASSERT(m_data); return m_features & (EvalFeature | WithFeature | CatchFeature); }
- bool needsActivation() const { ASSERT(m_data); return (hasCapturedVariables()) || (m_features & (EvalFeature | WithFeature | CatchFeature)); }
- bool hasCapturedVariables() const { return !!m_data->m_capturedVariables.size(); }
- size_t capturedVariableCount() const { return m_data->m_capturedVariables.size(); }
- bool captures(const Identifier& ident) { return m_data->m_capturedVariables.contains(ident.impl()); }
-
- VarStack& varStack() { ASSERT(m_data); return m_data->m_varStack; }
- FunctionStack& functionStack() { ASSERT(m_data); return m_data->m_functionStack; }
+ VarStack& varStack() { return m_varStack; }
+ FunctionStack& functionStack() { return m_functionStack; }
int neededConstants()
{
- ASSERT(m_data);
// We may need 2 more constants than the count given by the parser,
// because of the various uses of jsUndefined() and jsNull().
- return m_data->m_numConstants + 2;
+ return m_numConstants + 2;
}
StatementNode* singleStatement() const;
@@ -1433,22 +1445,27 @@ namespace JSC {
protected:
void setSource(const SourceCode& source) { m_source = source; }
+ ParserArena m_arena;
private:
- OwnPtr<ScopeNodeData> m_data;
- CodeFeatures m_features;
+ ScopeFlags m_scopeFlags;
SourceCode m_source;
+ VarStack m_varStack;
+ FunctionStack m_functionStack;
+ int m_numConstants;
+ SourceElements* m_statements;
+ IdentifierSet m_capturedVariables;
};
class ProgramNode : public ScopeNode {
public:
static const bool isFunctionNode = false;
- static PassRefPtr<ProgramNode> create(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+ static PassRefPtr<ProgramNode> create(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, ScopeFlags, int numConstants);
static const bool scopeIsFunction = false;
private:
- ProgramNode(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+ ProgramNode(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, ScopeFlags, int numConstants);
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
};
@@ -1456,12 +1473,12 @@ namespace JSC {
class EvalNode : public ScopeNode {
public:
static const bool isFunctionNode = false;
- static PassRefPtr<EvalNode> create(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+ static PassRefPtr<EvalNode> create(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, ScopeFlags, int numConstants);
static const bool scopeIsFunction = false;
private:
- EvalNode(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+ EvalNode(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, ScopeFlags, int numConstants);
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
};
@@ -1478,8 +1495,8 @@ namespace JSC {
class FunctionBodyNode : public ScopeNode {
public:
static const bool isFunctionNode = true;
- static FunctionBodyNode* create(JSGlobalData*, int, bool isStrictMode);
- static PassRefPtr<FunctionBodyNode> create(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+ static FunctionBodyNode* create(JSGlobalData*, int, ScopeFlags);
+ static PassRefPtr<FunctionBodyNode> create(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, ScopeFlags, int numConstants);
FunctionParameters* parameters() const { return m_parameters.get(); }
size_t parameterCount() const { return m_parameters->size(); }
@@ -1496,8 +1513,8 @@ namespace JSC {
static const bool scopeIsFunction = true;
private:
- FunctionBodyNode(JSGlobalData*, int, bool inStrictContext);
- FunctionBodyNode(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+ FunctionBodyNode(JSGlobalData*, int, ScopeFlags);
+ FunctionBodyNode(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, ScopeFlags, int numConstants);
Identifier m_ident;
Identifier m_inferredName;
diff --git a/Source/JavaScriptCore/parser/Parser.cpp b/Source/JavaScriptCore/parser/Parser.cpp
index 939d2696c..f58847fd2 100644
--- a/Source/JavaScriptCore/parser/Parser.cpp
+++ b/Source/JavaScriptCore/parser/Parser.cpp
@@ -62,11 +62,12 @@ Parser<LexerType>::Parser(JSGlobalData* globalData, const SourceCode& source, Fu
m_lexer->setCode(source, m_arena);
m_functionCache = source.provider()->cache();
- ScopeRef scope = pushScope();
- if (parserMode == JSParseFunctionCode)
- scope->setIsFunction();
+ ScopeFlags scopeFlags = NoScopeFlags;
if (strictness == JSParseStrict)
- scope->setStrictMode();
+ scopeFlags |= StrictModeFlag;
+ if (parserMode == JSParseFunctionCode)
+ scopeFlags |= FunctionModeFlag;
+ ScopeRef scope = pushScope(scopeFlags);
if (parameters) {
for (unsigned i = 0; i < parameters->size(); i++)
scope->declareParameter(&parameters->at(i));
@@ -96,16 +97,12 @@ UString Parser<LexerType>::parseInner()
IdentifierSet capturedVariables;
scope->getCapturedVariables(capturedVariables);
- CodeFeatures features = context.features();
- if (scope->strictMode())
- features |= StrictModeFeature;
- if (scope->shadowsArguments())
- features |= ShadowsArgumentsFeature;
+ ScopeFlags scopeFlags = scope->modeFlags() | scope->usesFlags();
unsigned functionCacheSize = m_functionCache ? m_functionCache->byteSize() : 0;
if (functionCacheSize != oldFunctionCacheSize)
m_lexer->sourceProvider()->notifyCacheSizeChanged(functionCacheSize - oldFunctionCacheSize);
- didFinishParsing(sourceElements, context.varDeclarations(), context.funcDeclarations(), features,
+ didFinishParsing(sourceElements, context.varDeclarations(), context.funcDeclarations(), scopeFlags,
m_lastLine, context.numConstants(), capturedVariables);
return parseError;
@@ -113,13 +110,13 @@ UString Parser<LexerType>::parseInner()
template <typename LexerType>
void Parser<LexerType>::didFinishParsing(SourceElements* sourceElements, ParserArenaData<DeclarationStacks::VarStack>* varStack,
- ParserArenaData<DeclarationStacks::FunctionStack>* funcStack, CodeFeatures features, int lastLine, int numConstants, IdentifierSet& capturedVars)
+ ParserArenaData<DeclarationStacks::FunctionStack>* funcStack, ScopeFlags scopeFlags, int lastLine, int numConstants, IdentifierSet& capturedVars)
{
m_sourceElements = sourceElements;
m_varDeclarations = varStack;
m_funcDeclarations = funcStack;
m_capturedVariables.swap(capturedVars);
- m_features = features;
+ m_scopeFlags = scopeFlags;
m_lastLine = lastLine;
m_numConstants = numConstants;
}
@@ -147,7 +144,7 @@ template <SourceElementsMode mode, class TreeBuilder> TreeSourceElements Parser<
if (directive) {
// "use strict" must be the exact literal without escape sequences or line continuation.
if (!hasSetStrict && directiveLiteralLength == lengthOfUseStrictLiteral && m_globalData->propertyNames->useStrictIdentifier == *directive) {
- setStrictMode();
+ currentScope()->setFlags(StrictModeFlag);
hasSetStrict = true;
failIfFalse(isValidStrictMode());
m_lexer->setOffset(startOffset);
@@ -255,6 +252,8 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseVarDeclarati
next();
bool hasInitializer = match(EQUAL);
failIfFalseIfStrictWithNameAndMessage(declareVariable(name), "Cannot declare a variable named", name->impl(), "in strict mode.");
+ if (m_globalData->propertyNames->arguments == *name)
+ currentScope()->setFlags(UsesArgumentsFlag);
context.addVar(name, (hasInitializer || (!m_allowsIn && match(INTOKEN))) ? DeclarationStacks::HasInitializer : 0);
if (hasInitializer) {
int varDivot = tokenStart() + 1;
@@ -289,6 +288,8 @@ template <class TreeBuilder> TreeConstDeclList Parser<LexerType>::parseConstDecl
next();
bool hasInitializer = match(EQUAL);
declareVariable(name);
+ if (m_globalData->propertyNames->arguments == *name)
+ currentScope()->setFlags(UsesArgumentsFlag);
context.addVar(name, DeclarationStacks::IsConstant | (hasInitializer ? DeclarationStacks::HasInitializer : 0));
TreeExpression initializer = 0;
if (hasInitializer) {
@@ -511,7 +512,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseWithStatement
{
ASSERT(match(WITH));
failIfTrueWithMessage(strictMode(), "'with' statements are not valid in strict mode");
- currentScope()->setNeedsFullActivation();
+ currentScope()->setFlags(UsesWithFlag);
int startLine = tokenLine();
next();
consumeOrFail(OPENPAREN);
@@ -526,6 +527,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseWithStatement
TreeStatement statement = parseStatement(context, unused);
failIfFalse(statement);
+ currentScope()->setFlags(UsesWithFlag);
return context.createWithStatement(m_lexer->lastLineNumber(), expr, statement, start, end, startLine, endLine);
}
@@ -614,15 +616,15 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseTryStatement(
int lastLine = m_lastLine;
if (match(CATCH)) {
- currentScope()->setNeedsFullActivation();
+ currentScope()->setFlags(UsesCatchFlag);
next();
consumeOrFail(OPENPAREN);
matchOrFail(IDENT);
ident = m_token.m_data.ident;
next();
- AutoPopScopeRef catchScope(this, pushScope());
+ AutoPopScopeRef catchScope(this, pushScope(currentScope()->modeFlags()));
failIfFalseIfStrictWithNameAndMessage(declareVariable(ident), "Cannot declare a variable named", ident->impl(), "in strict mode");
- catchScope->preventNewDecls();
+ currentScope()->setFlags(BlockScopeFlag | UsesCatchFlag);
consumeOrFail(CLOSEPAREN);
matchOrFail(OPENBRACE);
catchBlock = parseBlockStatement(context);
@@ -759,7 +761,7 @@ template <typename LexerType>
template <class TreeBuilder> TreeFunctionBody Parser<LexerType>::parseFunctionBody(TreeBuilder& context)
{
if (match(CLOSEBRACE))
- return context.createFunctionBody(m_lexer->lastLineNumber(), strictMode());
+ return context.createFunctionBody(m_lexer->lastLineNumber(), currentScope()->modeFlags());
DepthManager statementDepth(&m_statementDepth);
m_statementDepth = 0;
typename TreeBuilder::FunctionBodyBuilder bodyBuilder(const_cast<JSGlobalData*>(m_globalData), m_lexer.get());
@@ -770,8 +772,7 @@ template <class TreeBuilder> TreeFunctionBody Parser<LexerType>::parseFunctionBo
template <typename LexerType>
template <FunctionRequirements requirements, bool nameIsInContainingScope, class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuilder& context, const Identifier*& name, TreeFormalParameterList& parameters, TreeFunctionBody& body, int& openBracePos, int& closeBracePos, int& bodyStartLine)
{
- AutoPopScopeRef functionScope(this, pushScope());
- functionScope->setIsFunction();
+ AutoPopScopeRef functionScope(this, pushScope(currentScope()->modeFlags() | FunctionModeFlag));
if (match(IDENT)) {
name = m_token.m_data.ident;
next();
@@ -793,8 +794,8 @@ template <FunctionRequirements requirements, bool nameIsInContainingScope, class
// 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(openBracePos) : 0) {
// If we're in a strict context, the cached function info must say it was strict too.
- ASSERT(!strictMode() || cachedInfo->strictMode);
- body = context.createFunctionBody(m_lexer->lastLineNumber(), cachedInfo->strictMode);
+ ASSERT(!strictMode() || (cachedInfo->scopeFlags & StrictModeFlag));
+ body = context.createFunctionBody(m_lexer->lastLineNumber(), cachedInfo->scopeFlags);
functionScope->restoreFunctionInfo(cachedInfo);
failIfFalse(popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo));
@@ -854,6 +855,8 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseFunctionDecla
failIfFalse((parseFunctionInfo<FunctionNeedsName, true>(context, name, parameters, body, openBracePos, closeBracePos, bodyStartLine)));
failIfFalse(name);
failIfFalseIfStrict(declareVariable(name));
+ if (*name == m_globalData->propertyNames->arguments)
+ currentScope()->setFlags(UsesArgumentsFlag);
return context.createFuncDeclStatement(m_lexer->lastLineNumber(), name, body, parameters, openBracePos, closeBracePos, bodyStartLine, m_lastLine);
}
@@ -1204,7 +1207,6 @@ template <bool complete, class TreeBuilder> TreeProperty Parser<LexerType>::pars
return context.template createProperty<complete>(ident, node, PropertyNode::Constant);
}
failIfFalse(wasIdent);
- matchOrFail(IDENT);
const Identifier* accessorName = 0;
TreeFormalParameterList parameters = 0;
TreeFunctionBody body = 0;
@@ -1218,8 +1220,19 @@ template <bool complete, class TreeBuilder> TreeProperty Parser<LexerType>::pars
type = PropertyNode::Setter;
else
fail();
- failIfFalse((parseFunctionInfo<FunctionNeedsName, false>(context, accessorName, parameters, body, openBracePos, closeBracePos, bodyStartLine)));
- return context.template createGetterOrSetterProperty<complete>(m_lexer->lastLineNumber(), type, accessorName, parameters, body, openBracePos, closeBracePos, bodyStartLine, m_lastLine);
+ 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
+ fail();
+ next();
+ failIfFalse((parseFunctionInfo<FunctionNoRequirements, false>(context, accessorName, parameters, body, openBracePos, closeBracePos, bodyStartLine)));
+ if (stringPropertyName)
+ return context.template createGetterOrSetterProperty<complete>(m_lexer->lastLineNumber(), type, stringPropertyName, parameters, body, openBracePos, closeBracePos, bodyStartLine, m_lastLine);
+ return context.template createGetterOrSetterProperty<complete>(const_cast<JSGlobalData*>(m_globalData), m_lexer->lastLineNumber(), type, numericPropertyName, parameters, body, openBracePos, closeBracePos, bodyStartLine, m_lastLine);
}
case NUMBER: {
double propertyName = m_token.m_data.doubleValue;
@@ -1391,13 +1404,18 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePrimaryExpre
}
case THISTOKEN: {
next();
+ currentScope()->setFlags(UsesThisFlag);
return context.thisExpr(m_lexer->lastLineNumber());
}
case IDENT: {
int start = tokenStart();
const Identifier* ident = m_token.m_data.ident;
next();
- currentScope()->useVariable(ident, m_globalData->propertyNames->eval == *ident);
+ if (m_globalData->propertyNames->eval == *ident)
+ currentScope()->setFlags(UsesEvalFlag);
+ else if (m_globalData->propertyNames->arguments == *ident)
+ currentScope()->setFlags(UsesArgumentsFlag);
+ currentScope()->useVariable(ident);
m_lastIdentifier = ident;
return context.createResolve(m_lexer->lastLineNumber(), ident, start);
}
diff --git a/Source/JavaScriptCore/parser/Parser.h b/Source/JavaScriptCore/parser/Parser.h
index 9b76242d4..7513d1f11 100644
--- a/Source/JavaScriptCore/parser/Parser.h
+++ b/Source/JavaScriptCore/parser/Parser.h
@@ -130,30 +130,19 @@ struct ScopeLabelInfo {
};
struct Scope {
- Scope(const JSGlobalData* globalData, bool isFunction, bool strictMode)
+ Scope(const JSGlobalData* globalData, ScopeFlags scopeFlags)
: m_globalData(globalData)
- , m_shadowsArguments(false)
- , m_usesEval(false)
- , m_needsFullActivation(false)
- , m_allowsNewDecls(true)
- , m_strictMode(strictMode)
- , m_isFunction(isFunction)
- , m_isFunctionBoundary(false)
+ , m_scopeFlags(scopeFlags)
, m_isValidStrictMode(true)
, m_loopDepth(0)
, m_switchDepth(0)
{
+ ASSERT(!(scopeFlags & ~AllScopeModeFlags));
}
Scope(const Scope& rhs)
: m_globalData(rhs.m_globalData)
- , m_shadowsArguments(rhs.m_shadowsArguments)
- , m_usesEval(rhs.m_usesEval)
- , m_needsFullActivation(rhs.m_needsFullActivation)
- , m_allowsNewDecls(rhs.m_allowsNewDecls)
- , m_strictMode(rhs.m_strictMode)
- , m_isFunction(rhs.m_isFunction)
- , m_isFunctionBoundary(rhs.m_isFunctionBoundary)
+ , m_scopeFlags(rhs.m_scopeFlags)
, m_isValidStrictMode(rhs.m_isValidStrictMode)
, m_loopDepth(rhs.m_loopDepth)
, m_switchDepth(rhs.m_switchDepth)
@@ -168,6 +157,22 @@ struct Scope {
}
}
+ ALWAYS_INLINE ScopeFlags scopeFlags() const { return m_scopeFlags; }
+ ALWAYS_INLINE ScopeFlags modeFlags() const { return m_scopeFlags & AllScopeModeFlags; }
+ ALWAYS_INLINE ScopeFlags usesFlags() const { return m_scopeFlags & AllScopeUsesFlags; }
+ ALWAYS_INLINE void setFlags(ScopeFlags scopeFlags) { m_scopeFlags |= scopeFlags; }
+
+ ALWAYS_INLINE bool needsFullActivation() const { return m_scopeFlags & (UsesEvalFlag | UsesWithFlag | UsesCatchFlag); }
+ ALWAYS_INLINE bool strictMode() const { return m_scopeFlags & StrictModeFlag; }
+ ALWAYS_INLINE bool shadowsArguments() const { return m_scopeFlags & ShadowsArgumentsFlag; }
+ ALWAYS_INLINE bool isFunction() const { return m_scopeFlags & FunctionModeFlag; }
+ ALWAYS_INLINE bool isBlockScope() const { return m_scopeFlags & BlockScopeFlag; }
+ ALWAYS_INLINE bool isFunctionBoundary() const { return isFunction() && !isBlockScope(); }
+
+ ALWAYS_INLINE bool allowsNewDecls() const { return !isBlockScope(); }
+
+ ALWAYS_INLINE bool isValidStrictMode() const { return m_isValidStrictMode; }
+
void startSwitch() { m_switchDepth++; }
void endSwitch() { m_switchDepth--; }
void startLoop() { m_loopDepth++; }
@@ -201,14 +206,6 @@ struct Scope {
return 0;
}
- void setIsFunction()
- {
- m_isFunction = true;
- m_isFunctionBoundary = true;
- }
- bool isFunction() { return m_isFunction; }
- bool isFunctionBoundary() { return m_isFunctionBoundary; }
-
bool declareVariable(const Identifier* ident)
{
bool isValidStrictMode = m_globalData->propertyNames->eval != *ident && m_globalData->propertyNames->arguments != *ident;
@@ -219,35 +216,28 @@ struct Scope {
void declareWrite(const Identifier* ident)
{
- ASSERT(m_strictMode);
+ ASSERT(strictMode());
m_writtenVariables.add(ident->impl());
}
- void preventNewDecls() { m_allowsNewDecls = false; }
- bool allowsNewDecls() const { return m_allowsNewDecls; }
-
bool declareParameter(const Identifier* ident)
{
bool isArguments = m_globalData->propertyNames->arguments == *ident;
bool isValidStrictMode = m_declaredVariables.add(ident->ustring().impl()).second && m_globalData->propertyNames->eval != *ident && !isArguments;
m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
if (isArguments)
- m_shadowsArguments = true;
+ setFlags(ShadowsArgumentsFlag);
return isValidStrictMode;
}
- void useVariable(const Identifier* ident, bool isEval)
+ void useVariable(const Identifier* ident)
{
- m_usesEval |= isEval;
m_usedVariables.add(ident->ustring().impl());
}
- void setNeedsFullActivation() { m_needsFullActivation = true; }
-
bool collectFreeVariables(Scope* nestedScope, bool shouldTrackClosedVariables)
{
- if (nestedScope->m_usesEval)
- m_usesEval = true;
+ setFlags(nestedScope->usesFlags());
IdentifierSet::iterator end = nestedScope->m_usedVariables.end();
for (IdentifierSet::iterator ptr = nestedScope->m_usedVariables.begin(); ptr != end; ++ptr) {
if (nestedScope->m_declaredVariables.contains(*ptr))
@@ -279,7 +269,7 @@ struct Scope {
void getCapturedVariables(IdentifierSet& capturedVariables)
{
- if (m_needsFullActivation || m_usesEval) {
+ if (needsFullActivation()) {
capturedVariables.swap(m_declaredVariables);
return;
}
@@ -289,11 +279,6 @@ struct Scope {
capturedVariables.add(*ptr);
}
}
- void setStrictMode() { m_strictMode = true; }
- bool strictMode() const { return m_strictMode; }
- bool isValidStrictMode() const { return m_isValidStrictMode; }
- bool shadowsArguments() const { return m_shadowsArguments; }
-
void copyCapturedVariablesToVector(const IdentifierSet& capturedVariables, Vector<RefPtr<StringImpl> >& vector)
{
IdentifierSet::iterator end = capturedVariables.end();
@@ -307,20 +292,16 @@ struct Scope {
void saveFunctionInfo(SourceProviderCacheItem* info)
{
- ASSERT(m_isFunction);
- info->usesEval = m_usesEval;
- info->strictMode = m_strictMode;
- info->needsFullActivation = m_needsFullActivation;
+ ASSERT(isFunction());
+ info->scopeFlags = m_scopeFlags;
copyCapturedVariablesToVector(m_writtenVariables, info->writtenVariables);
copyCapturedVariablesToVector(m_usedVariables, info->usedVariables);
}
void restoreFunctionInfo(const SourceProviderCacheItem* info)
{
- ASSERT(m_isFunction);
- m_usesEval = info->usesEval;
- m_strictMode = info->strictMode;
- m_needsFullActivation = info->needsFullActivation;
+ ASSERT(isFunction());
+ m_scopeFlags |= info->scopeFlags;
unsigned size = info->usedVariables.size();
for (unsigned i = 0; i < size; ++i)
m_usedVariables.add(info->usedVariables[i]);
@@ -331,13 +312,7 @@ struct Scope {
private:
const JSGlobalData* m_globalData;
- bool m_shadowsArguments : 1;
- bool m_usesEval : 1;
- bool m_needsFullActivation : 1;
- bool m_allowsNewDecls : 1;
- bool m_strictMode : 1;
- bool m_isFunction : 1;
- bool m_isFunctionBoundary : 1;
+ ScopeFlags m_scopeFlags;
bool m_isValidStrictMode : 1;
int m_loopDepth;
int m_switchDepth;
@@ -427,20 +402,14 @@ private:
Parser* m_parser;
};
- ScopeRef currentScope()
+ ALWAYS_INLINE ScopeRef currentScope()
{
return ScopeRef(&m_scopeStack, m_scopeStack.size() - 1);
}
- ScopeRef pushScope()
+ ScopeRef pushScope(ScopeFlags scopeFlags)
{
- bool isFunction = false;
- bool isStrict = false;
- if (!m_scopeStack.isEmpty()) {
- isStrict = m_scopeStack.last().strictMode();
- isFunction = m_scopeStack.last().isFunction();
- }
- m_scopeStack.append(Scope(m_globalData, isFunction, isStrict));
+ m_scopeStack.append(Scope(m_globalData, scopeFlags));
return currentScope();
}
@@ -492,7 +461,7 @@ private:
UString parseInner();
void didFinishParsing(SourceElements*, ParserArenaData<DeclarationStacks::VarStack>*,
- ParserArenaData<DeclarationStacks::FunctionStack>*, CodeFeatures,
+ ParserArenaData<DeclarationStacks::FunctionStack>*, ScopeFlags,
int, int, IdentifierSet&);
// Used to determine type of error to report.
@@ -823,14 +792,13 @@ private:
m_errorMessage = UString(msg);
}
- void startLoop() { currentScope()->startLoop(); }
- void endLoop() { currentScope()->endLoop(); }
- void startSwitch() { currentScope()->startSwitch(); }
- void endSwitch() { currentScope()->endSwitch(); }
- void setStrictMode() { currentScope()->setStrictMode(); }
- bool strictMode() { return currentScope()->strictMode(); }
- bool isValidStrictMode() { return currentScope()->isValidStrictMode(); }
- bool declareParameter(const Identifier* ident) { return currentScope()->declareParameter(ident); }
+ ALWAYS_INLINE void startLoop() { currentScope()->startLoop(); }
+ ALWAYS_INLINE void endLoop() { currentScope()->endLoop(); }
+ ALWAYS_INLINE void startSwitch() { currentScope()->startSwitch(); }
+ ALWAYS_INLINE void endSwitch() { currentScope()->endSwitch(); }
+ ALWAYS_INLINE bool strictMode() { return currentScope()->strictMode(); }
+ ALWAYS_INLINE bool isValidStrictMode() { return currentScope()->isValidStrictMode(); }
+ ALWAYS_INLINE bool declareParameter(const Identifier* ident) { return currentScope()->declareParameter(ident); }
bool breakIsValid()
{
ScopeRef current = currentScope();
@@ -949,7 +917,7 @@ private:
ParserArenaData<DeclarationStacks::VarStack>* m_varDeclarations;
ParserArenaData<DeclarationStacks::FunctionStack>* m_funcDeclarations;
IdentifierSet m_capturedVariables;
- CodeFeatures m_features;
+ ScopeFlags m_scopeFlags;
int m_numConstants;
struct DepthManager {
@@ -1010,7 +978,7 @@ PassRefPtr<ParsedNode> Parser<LexerType>::parse(JSGlobalObject* lexicalGlobalObj
m_funcDeclarations ? &m_funcDeclarations->data : 0,
m_capturedVariables,
*m_source,
- m_features,
+ m_scopeFlags,
m_numConstants);
result->setLoc(m_source->firstLine(), m_lastLine);
} else if (lexicalGlobalObject) {
diff --git a/Source/JavaScriptCore/parser/ParserArena.cpp b/Source/JavaScriptCore/parser/ParserArena.cpp
index 56c58dacf..c53f30753 100644
--- a/Source/JavaScriptCore/parser/ParserArena.cpp
+++ b/Source/JavaScriptCore/parser/ParserArena.cpp
@@ -34,7 +34,6 @@ namespace JSC {
ParserArena::ParserArena()
: m_freeableMemory(0)
, m_freeablePoolEnd(0)
- , m_identifierArena(adoptPtr(new IdentifierArena))
{
}
@@ -88,7 +87,8 @@ void ParserArena::reset()
m_freeableMemory = 0;
m_freeablePoolEnd = 0;
- m_identifierArena->clear();
+ if (m_identifierArena)
+ m_identifierArena->clear();
m_freeablePools.clear();
m_deletableObjects.clear();
m_refCountedObjects.clear();
@@ -108,7 +108,7 @@ void ParserArena::allocateFreeablePool()
bool ParserArena::isEmpty() const
{
return !m_freeablePoolEnd
- && m_identifierArena->isEmpty()
+ && (!m_identifierArena || m_identifierArena->isEmpty())
&& m_freeablePools.isEmpty()
&& m_deletableObjects.isEmpty()
&& m_refCountedObjects.isEmpty();
diff --git a/Source/JavaScriptCore/parser/ParserArena.h b/Source/JavaScriptCore/parser/ParserArena.h
index 49f0ab6bf..067b83a26 100644
--- a/Source/JavaScriptCore/parser/ParserArena.h
+++ b/Source/JavaScriptCore/parser/ParserArena.h
@@ -161,7 +161,12 @@ namespace JSC {
bool isEmpty() const;
JS_EXPORT_PRIVATE void reset();
- IdentifierArena& identifierArena() { return *m_identifierArena; }
+ IdentifierArena& identifierArena()
+ {
+ if (UNLIKELY (!m_identifierArena))
+ m_identifierArena = adoptPtr(new IdentifierArena);
+ return *m_identifierArena;
+ }
private:
static const size_t freeablePoolSize = 8000;
diff --git a/Source/JavaScriptCore/parser/ResultType.h b/Source/JavaScriptCore/parser/ResultType.h
index 27b8112a0..8f30e5b64 100644
--- a/Source/JavaScriptCore/parser/ResultType.h
+++ b/Source/JavaScriptCore/parser/ResultType.h
@@ -32,8 +32,7 @@ namespace JSC {
friend struct OperandTypes;
typedef char Type;
- static const Type TypeReusable = 1;
- static const Type TypeInt32 = 2;
+ static const Type TypeInt32 = 1;
static const Type TypeMaybeNumber = 0x04;
static const Type TypeMaybeString = 0x08;
@@ -48,11 +47,6 @@ namespace JSC {
{
}
- bool isReusable()
- {
- return m_type & TypeReusable;
- }
-
bool isInt32()
{
return m_type & TypeInt32;
@@ -93,19 +87,14 @@ namespace JSC {
return ResultType(TypeMaybeNumber);
}
- static ResultType numberTypeCanReuse()
- {
- return ResultType(TypeReusable | TypeMaybeNumber);
- }
-
- static ResultType numberTypeCanReuseIsInt32()
+ static ResultType numberTypeIsInt32()
{
- return ResultType(TypeReusable | TypeInt32 | TypeMaybeNumber);
+ return ResultType(TypeInt32 | TypeMaybeNumber);
}
- static ResultType stringOrNumberTypeCanReuse()
+ static ResultType stringOrNumberType()
{
- return ResultType(TypeReusable | TypeMaybeNumber | TypeMaybeString);
+ return ResultType(TypeMaybeNumber | TypeMaybeString);
}
static ResultType stringType()
@@ -121,15 +110,15 @@ namespace JSC {
static ResultType forAdd(ResultType op1, ResultType op2)
{
if (op1.definitelyIsNumber() && op2.definitelyIsNumber())
- return numberTypeCanReuse();
+ return numberType();
if (op1.definitelyIsString() || op2.definitelyIsString())
return stringType();
- return stringOrNumberTypeCanReuse();
+ return stringOrNumberType();
}
static ResultType forBitOp()
{
- return numberTypeCanReuseIsInt32();
+ return numberTypeIsInt32();
}
private:
diff --git a/Source/JavaScriptCore/parser/SourceProvider.h b/Source/JavaScriptCore/parser/SourceProvider.h
index dfc8d88e2..f66a921f5 100644
--- a/Source/JavaScriptCore/parser/SourceProvider.h
+++ b/Source/JavaScriptCore/parser/SourceProvider.h
@@ -47,7 +47,7 @@ namespace JSC {
, m_cache(cache ? cache : new SourceProviderCache)
, m_cacheOwned(!cache)
{
- deprecatedTurnOffVerifier();
+ turnOffVerifier();
}
virtual ~SourceProvider()
{
diff --git a/Source/JavaScriptCore/parser/SourceProviderCacheItem.h b/Source/JavaScriptCore/parser/SourceProviderCacheItem.h
index 3662367a0..ad7a759ce 100644
--- a/Source/JavaScriptCore/parser/SourceProviderCacheItem.h
+++ b/Source/JavaScriptCore/parser/SourceProviderCacheItem.h
@@ -61,9 +61,7 @@ public:
int closeBraceLine;
int closeBracePos;
- bool usesEval;
- bool strictMode;
- bool needsFullActivation;
+ unsigned short scopeFlags;
Vector<RefPtr<StringImpl> > usedVariables;
Vector<RefPtr<StringImpl> > writtenVariables;
};
diff --git a/Source/JavaScriptCore/parser/SyntaxChecker.h b/Source/JavaScriptCore/parser/SyntaxChecker.h
index 32cbf7d6c..2acb5097d 100644
--- a/Source/JavaScriptCore/parser/SyntaxChecker.h
+++ b/Source/JavaScriptCore/parser/SyntaxChecker.h
@@ -210,11 +210,16 @@ public:
return Property(type);
return Property(name, type);
}
+ template <bool strict> Property createGetterOrSetterProperty(JSGlobalData* globalData, int, PropertyNode::Type type, double name, int, int, int, int, int, int)
+ {
+ if (!strict)
+ return Property(type);
+ return Property(&globalData->parserArena->identifierArena().makeNumericIdentifier(globalData, name), type);
+ }
void appendStatement(int, int) { }
void addVar(const Identifier*, bool) { }
int combineCommaNodes(int, int, int) { return 1; }
- int evalCount() const { return 0; }
void appendBinaryExpressionInfo(int& operandStackDepth, int expr, int, int, int, bool)
{
if (!m_topBinaryExpr)
diff --git a/Source/JavaScriptCore/runtime/Arguments.cpp b/Source/JavaScriptCore/runtime/Arguments.cpp
index a099adb75..7a53ec1a4 100644
--- a/Source/JavaScriptCore/runtime/Arguments.cpp
+++ b/Source/JavaScriptCore/runtime/Arguments.cpp
@@ -196,7 +196,7 @@ void Arguments::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyN
JSObject::getOwnPropertyNames(thisObject, exec, propertyNames, mode);
}
-void Arguments::putByIndex(JSCell* cell, ExecState* exec, unsigned i, JSValue value)
+void Arguments::putByIndex(JSCell* cell, ExecState* exec, unsigned i, JSValue value, bool shouldThrow)
{
Arguments* thisObject = jsCast<Arguments*>(cell);
if (i < static_cast<unsigned>(thisObject->d->numArguments) && (!thisObject->d->deletedArguments || !thisObject->d->deletedArguments[i])) {
@@ -204,7 +204,7 @@ void Arguments::putByIndex(JSCell* cell, ExecState* exec, unsigned i, JSValue va
return;
}
- PutPropertySlot slot;
+ PutPropertySlot slot(shouldThrow);
JSObject::put(thisObject, exec, Identifier(exec, UString::number(i)), value, slot);
}
@@ -320,12 +320,15 @@ bool Arguments::defineOwnProperty(JSObject* object, ExecState* exec, const Ident
if (descriptor.isAccessorDescriptor()) {
// i. Call the [[Delete]] internal method of map passing P, and false as the arguments.
thisObject->d->deletedArguments[i] = true;
- } else if (descriptor.value()) { // b. Else i. If Desc.[[Value]] is present, then
+ } 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->argument(i).set(exec->globalData(), thisObject, descriptor.value());
// ii. If Desc.[[Writable]] is present and its value is false, then
- thisObject->argument(i).set(exec->globalData(), thisObject, descriptor.value());
+ // 1. Call the [[Delete]] internal method of map passing P and false as arguments.
if (descriptor.writablePresent() && !descriptor.writable())
- thisObject->d->deletedArguments[i] = true; // 1. Call the [[Delete]] internal method of map passing P and false as arguments.
+ thisObject->d->deletedArguments[i] = true;
}
}
diff --git a/Source/JavaScriptCore/runtime/Arguments.h b/Source/JavaScriptCore/runtime/Arguments.h
index ee54a49eb..8e7af1844 100644
--- a/Source/JavaScriptCore/runtime/Arguments.h
+++ b/Source/JavaScriptCore/runtime/Arguments.h
@@ -114,7 +114,7 @@ namespace JSC {
static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
static void put(JSCell*, ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
- static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue);
+ static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
static bool deleteProperty(JSCell*, ExecState*, const Identifier& propertyName);
static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName);
static bool defineOwnProperty(JSObject*, ExecState*, const Identifier& propertyName, PropertyDescriptor&, bool shouldThrow);
diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
index cb9b12a59..2f000fc74 100644
--- a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
@@ -166,6 +166,90 @@ 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.
+//
+// header currentCount (remainder)
+// [------][------------][-----------]
+// header resultCount (remainder)
+// [------][-----------][-----------]
+//
+// The set of properties in the range 'header' must be unchanged. The set of
+// properties in the range 'remainder' (where remainder = length - header -
+// 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.
+static inline void shift(ExecState* exec, JSObject* thisObj, unsigned header, unsigned currentCount, unsigned resultCount, unsigned length)
+{
+ ASSERT(currentCount > resultCount);
+ unsigned count = currentCount - resultCount;
+
+ ASSERT(header <= length);
+ ASSERT(currentCount <= (length - header));
+
+ if (!header && isJSArray(thisObj) && asArray(thisObj)->shiftCount(exec, 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 (exec->hadException())
+ return;
+ thisObj->methodTable()->putByIndex(thisObj, exec, to, value, true);
+ if (exec->hadException())
+ return;
+ } else if (!thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, to)) {
+ throwTypeError(exec, "Unable to delete property.");
+ return;
+ }
+ }
+ for (unsigned k = length; k > length - count; --k) {
+ if (!thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, k - 1)) {
+ throwTypeError(exec, "Unable to delete property.");
+ return;
+ }
+ }
+}
+static inline void unshift(ExecState* exec, JSObject* thisObj, unsigned header, unsigned currentCount, unsigned resultCount, unsigned length)
+{
+ ASSERT(resultCount > currentCount);
+ unsigned count = resultCount - currentCount;
+
+ ASSERT(header <= length);
+ ASSERT(currentCount <= (length - header));
+
+ // Guard against overflow.
+ if (count > (UINT_MAX - length)) {
+ throwOutOfMemoryError(exec);
+ return;
+ }
+
+ if (!header && isJSArray(thisObj) && asArray(thisObj)->unshiftCount(exec, 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 (exec->hadException())
+ return;
+ thisObj->methodTable()->putByIndex(thisObj, exec, to, value, true);
+ } else if (!thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, to)) {
+ throwTypeError(exec, "Unable to delete property.");
+ return;
+ }
+ if (exec->hadException())
+ return;
+ }
+}
+
EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec)
{
JSValue thisValue = exec->hostThisValue();
@@ -265,9 +349,13 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec)
strBuffer.append(',');
JSValue element = thisObj->get(exec, k);
+ 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());
UString str;
CallData callData;
CallType callType = getCallData(conversionFunction, callData);
@@ -275,6 +363,8 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec)
str = call(exec, conversionFunction, callType, callData, element, exec->emptyList()).toString(exec)->value(exec);
else
str = element.toString(exec)->value(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
strBuffer.append(str);
}
}
@@ -368,11 +458,11 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState* exec)
if (exec->hadException())
return JSValue::encode(jsUndefined());
if (v)
- arr->methodTable()->putByIndex(arr, exec, n, v);
+ arr->putDirectIndex(exec, n, v);
n++;
}
} else {
- arr->methodTable()->putByIndex(arr, exec, n, curArg);
+ arr->putDirectIndex(exec, n, curArg);
n++;
}
if (i == argCount)
@@ -402,7 +492,12 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncPop(ExecState* exec)
result = jsUndefined();
} else {
result = thisObj->get(exec, length - 1);
- thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, length - 1);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+ if (!thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, length - 1)) {
+ throwTypeError(exec, "Unable to delete property.");
+ return JSValue::encode(jsUndefined());
+ }
putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(length - 1));
}
return JSValue::encode(result);
@@ -426,12 +521,14 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState* exec)
for (unsigned n = 0; n < exec->argumentCount(); n++) {
// Check for integer overflow; where safe we can do a fast put by index.
if (length + n >= length)
- thisObj->methodTable()->putByIndex(thisObj, exec, length + n, exec->argument(n));
+ thisObj->methodTable()->putByIndex(thisObj, exec, length + n, exec->argument(n), true);
else {
PutPropertySlot slot;
Identifier propertyName(exec, JSValue(static_cast<int64_t>(length) + static_cast<int64_t>(n)).toString(exec)->value(exec));
thisObj->methodTable()->put(thisObj, exec, propertyName, exec->argument(n), slot);
}
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
}
JSValue newLength(static_cast<int64_t>(length) + static_cast<int64_t>(exec->argumentCount()));
putProperty(exec, thisObj, exec->propertyNames().length, newLength);
@@ -455,15 +552,23 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncReverse(ExecState* exec)
if (exec->hadException())
return JSValue::encode(jsUndefined());
- if (obj2)
- thisObj->methodTable()->putByIndex(thisObj, exec, k, obj2);
- else
- thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, k);
+ if (obj2) {
+ thisObj->methodTable()->putByIndex(thisObj, exec, k, obj2, true);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+ } else if (!thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, k)) {
+ throwTypeError(exec, "Unable to delete property.");
+ return JSValue::encode(jsUndefined());
+ }
- if (obj)
- thisObj->methodTable()->putByIndex(thisObj, exec, lk1, obj);
- else
- thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, lk1);
+ if (obj) {
+ thisObj->methodTable()->putByIndex(thisObj, exec, lk1, obj, true);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+ } else if (!thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, lk1)) {
+ throwTypeError(exec, "Unable to delete property.");
+ return JSValue::encode(jsUndefined());
+ }
}
return JSValue::encode(thisObj);
}
@@ -481,20 +586,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncShift(ExecState* exec)
result = jsUndefined();
} else {
result = thisObj->get(exec, 0);
- if (isJSArray(thisObj))
- ((JSArray *)thisObj)->shiftCount(exec, 1);
- else {
- for (unsigned k = 1; k < length; k++) {
- JSValue obj = getProperty(exec, thisObj, k);
- if (exec->hadException())
- return JSValue::encode(jsUndefined());
- if (obj)
- thisObj->methodTable()->putByIndex(thisObj, exec, k - 1, obj);
- else
- thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, k - 1);
- }
- thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, length - 1);
- }
+ shift(exec, thisObj, 0, 1, 0, length);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(length - 1));
}
return JSValue::encode(result);
@@ -521,7 +615,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSlice(ExecState* exec)
if (exec->hadException())
return JSValue::encode(jsUndefined());
if (v)
- resObj->methodTable()->putByIndex(resObj, exec, n, v);
+ resObj->putDirectIndex(exec, n, v);
}
resObj->setLength(exec, n);
return JSValue::encode(result);
@@ -580,8 +674,12 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState* exec)
}
// Swap themin and i
if (themin > i) {
- thisObj->methodTable()->putByIndex(thisObj, exec, i, minObj);
- thisObj->methodTable()->putByIndex(thisObj, exec, themin, iObj);
+ thisObj->methodTable()->putByIndex(thisObj, exec, i, minObj, true);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+ thisObj->methodTable()->putByIndex(thisObj, exec, themin, iObj, true);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
}
}
return JSValue::encode(thisObj);
@@ -627,41 +725,20 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec)
resObj->completeInitialization(deleteCount);
unsigned additionalArgs = std::max<int>(exec->argumentCount() - 2, 0);
- if (additionalArgs != deleteCount) {
- if (additionalArgs < deleteCount) {
- if ((!begin) && (isJSArray(thisObj)))
- ((JSArray *)thisObj)->shiftCount(exec, deleteCount - additionalArgs);
- else {
- for (unsigned k = begin; k < length - deleteCount; ++k) {
- JSValue v = getProperty(exec, thisObj, k + deleteCount);
- if (exec->hadException())
- return JSValue::encode(jsUndefined());
- if (v)
- thisObj->methodTable()->putByIndex(thisObj, exec, k + additionalArgs, v);
- else
- thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, k + additionalArgs);
- }
- for (unsigned k = length; k > length - deleteCount + additionalArgs; --k)
- thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, k - 1);
- }
- } else {
- if ((!begin) && (isJSArray(thisObj)))
- ((JSArray *)thisObj)->unshiftCount(exec, additionalArgs - deleteCount);
- else {
- for (unsigned k = length - deleteCount; k > begin; --k) {
- JSValue obj = getProperty(exec, thisObj, k + deleteCount - 1);
- if (exec->hadException())
- return JSValue::encode(jsUndefined());
- if (obj)
- thisObj->methodTable()->putByIndex(thisObj, exec, k + additionalArgs - 1, obj);
- else
- thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, k + additionalArgs - 1);
- }
- }
- }
+ if (additionalArgs < deleteCount) {
+ shift(exec, thisObj, begin, deleteCount, additionalArgs, length);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+ } else if (additionalArgs > deleteCount) {
+ unshift(exec, thisObj, begin, deleteCount, additionalArgs, length);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+ }
+ for (unsigned k = 0; k < additionalArgs; ++k) {
+ thisObj->methodTable()->putByIndex(thisObj, exec, k + begin, exec->argument(k + 2), true);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
}
- for (unsigned k = 0; k < additionalArgs; ++k)
- thisObj->methodTable()->putByIndex(thisObj, exec, k + begin, exec->argument(k + 2));
putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(length - deleteCount + additionalArgs));
return JSValue::encode(result);
@@ -677,23 +754,16 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncUnShift(ExecState* exec)
return JSValue::encode(jsUndefined());
unsigned nrArgs = exec->argumentCount();
- if ((nrArgs) && (length)) {
- if (isJSArray(thisObj))
- ((JSArray *)thisObj)->unshiftCount(exec, nrArgs);
- else {
- for (unsigned k = length; k > 0; --k) {
- JSValue v = getProperty(exec, thisObj, k - 1);
- if (exec->hadException())
- return JSValue::encode(jsUndefined());
- if (v)
- thisObj->methodTable()->putByIndex(thisObj, exec, k + nrArgs - 1, v);
- else
- thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, k + nrArgs - 1);
- }
- }
+ if (nrArgs) {
+ unshift(exec, thisObj, 0, 0, nrArgs, length);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+ }
+ for (unsigned k = 0; k < nrArgs; ++k) {
+ thisObj->methodTable()->putByIndex(thisObj, exec, k, exec->argument(k), true);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
}
- for (unsigned k = 0; k < nrArgs; ++k)
- thisObj->methodTable()->putByIndex(thisObj, exec, k, exec->argument(k));
JSValue result = jsNumber(length + nrArgs);
putProperty(exec, thisObj, exec->propertyNames().length, result);
return JSValue::encode(result);
@@ -732,7 +802,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncFilter(ExecState* exec)
JSValue result = cachedCall.call();
if (result.toBoolean(exec))
- resultArray->methodTable()->putByIndex(resultArray, exec, filterIndex++, v);
+ resultArray->putDirectIndex(exec, filterIndex++, v);
}
if (k == length)
return JSValue::encode(resultArray);
@@ -753,7 +823,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncFilter(ExecState* exec)
JSValue result = call(exec, function, callType, callData, applyThis, eachArguments);
if (result.toBoolean(exec))
- resultArray->methodTable()->putByIndex(resultArray, exec, filterIndex++, v);
+ resultArray->putDirectIndex(exec, filterIndex++, v);
}
return JSValue::encode(resultArray);
}
@@ -788,7 +858,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncMap(ExecState* exec)
cachedCall.setArgument(1, jsNumber(k));
cachedCall.setArgument(2, thisObj);
- JSArray::putByIndex(resultArray, exec, k, cachedCall.call());
+ resultArray->putDirectIndex(exec, k, cachedCall.call());
}
}
for (; k < length && !exec->hadException(); ++k) {
@@ -809,7 +879,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncMap(ExecState* exec)
return JSValue::encode(jsUndefined());
JSValue result = call(exec, function, callType, callData, applyThis, eachArguments);
- resultArray->methodTable()->putByIndex(resultArray, exec, k, result);
+ resultArray->putDirectIndex(exec, k, result);
}
return JSValue::encode(resultArray);
diff --git a/Source/JavaScriptCore/runtime/ClassInfo.h b/Source/JavaScriptCore/runtime/ClassInfo.h
index 9ebb33a74..214258cc6 100644
--- a/Source/JavaScriptCore/runtime/ClassInfo.h
+++ b/Source/JavaScriptCore/runtime/ClassInfo.h
@@ -48,7 +48,7 @@ namespace JSC {
typedef void (*PutFunctionPtr)(JSCell*, ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
PutFunctionPtr put;
- typedef void (*PutByIndexFunctionPtr)(JSCell*, ExecState*, unsigned propertyName, JSValue);
+ typedef void (*PutByIndexFunctionPtr)(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
PutByIndexFunctionPtr putByIndex;
typedef bool (*DeletePropertyFunctionPtr)(JSCell*, ExecState*, const Identifier&);
diff --git a/Source/JavaScriptCore/runtime/CommonIdentifiers.h b/Source/JavaScriptCore/runtime/CommonIdentifiers.h
index d79e5c783..0d9580197 100644
--- a/Source/JavaScriptCore/runtime/CommonIdentifiers.h
+++ b/Source/JavaScriptCore/runtime/CommonIdentifiers.h
@@ -27,10 +27,6 @@
// 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(__defineGetter__) \
- macro(__defineSetter__) \
- macro(__lookupGetter__) \
- macro(__lookupSetter__) \
macro(apply) \
macro(arguments) \
macro(bind) \
@@ -52,6 +48,7 @@
macro(input) \
macro(isArray) \
macro(isPrototypeOf) \
+ macro(lastIndex) \
macro(length) \
macro(message) \
macro(multiline) \
diff --git a/Source/JavaScriptCore/runtime/Completion.cpp b/Source/JavaScriptCore/runtime/Completion.cpp
index 98a66589a..ce620245b 100644
--- a/Source/JavaScriptCore/runtime/Completion.cpp
+++ b/Source/JavaScriptCore/runtime/Completion.cpp
@@ -30,7 +30,7 @@
#include "Interpreter.h"
#include "Parser.h"
#include "Debugger.h"
-#include "WTFThreadData.h"
+#include <wtf/WTFThreadData.h>
#include <stdio.h>
namespace JSC {
diff --git a/Source/JavaScriptCore/runtime/Error.cpp b/Source/JavaScriptCore/runtime/Error.cpp
index 243dc8856..5266c1ebe 100644
--- a/Source/JavaScriptCore/runtime/Error.cpp
+++ b/Source/JavaScriptCore/runtime/Error.cpp
@@ -36,6 +36,8 @@
#include "NativeErrorConstructor.h"
#include "SourceCode.h"
+#include <wtf/text/StringBuilder.h>
+
namespace JSC {
static const char* linePropertyName = "line";
@@ -132,20 +134,14 @@ JSObject* addErrorInfo(JSGlobalData* globalData, JSObject* error, int line, cons
globalObject = globalData->dynamicGlobalObject;
else
globalObject = error->globalObject();
- // We use the tryCreateUninitialized creation mechanism and related initialization
- // functions as they're the only mechanism we currently have that will guarantee we
- // don't call setters on the prototype. Technically it's faster than the alternative,
- // but the numerous allocations that take place in this loop makes that last bit
- // somewhat moot.
- JSArray* stackTraceArray = JSArray::tryCreateUninitialized(*globalData, globalObject->arrayStructure(), stackTrace.size());
- if (!stackTraceArray)
- return error;
+ StringBuilder builder;
for (unsigned i = 0; i < stackTrace.size(); i++) {
- UString stackLevel = stackTrace[i].toString(globalObject->globalExec());
- stackTraceArray->initializeIndex(*globalData, i, jsString(globalData, stackLevel));
+ builder.append(String(stackTrace[i].toString(globalObject->globalExec()).impl()));
+ if (i != stackTrace.size() - 1)
+ builder.append('\n');
}
- stackTraceArray->completeInitialization(stackTrace.size());
- error->putDirect(*globalData, globalData->propertyNames->stack, stackTraceArray, ReadOnly | DontDelete);
+
+ error->putDirect(*globalData, globalData->propertyNames->stack, jsString(globalData, UString(builder.toString().impl())), ReadOnly | DontDelete);
}
return error;
diff --git a/Source/JavaScriptCore/runtime/Executable.cpp b/Source/JavaScriptCore/runtime/Executable.cpp
index 25ddf764a..ea40447e4 100644
--- a/Source/JavaScriptCore/runtime/Executable.cpp
+++ b/Source/JavaScriptCore/runtime/Executable.cpp
@@ -34,7 +34,7 @@
#include "JITDriver.h"
#include "Parser.h"
#include "UStringBuilder.h"
-#include "Vector.h"
+#include <wtf/Vector.h>
namespace JSC {
@@ -177,10 +177,9 @@ JSObject* EvalExecutable::compileOptimized(ExecState* exec, ScopeChainNode* scop
}
#if ENABLE(JIT)
-void EvalExecutable::jitCompile(JSGlobalData& globalData)
+bool EvalExecutable::jitCompile(JSGlobalData& globalData)
{
- bool result = jitCompileIfAppropriate(globalData, m_evalCodeBlock, m_jitCodeForCall, JITCode::bottomTierJIT());
- ASSERT_UNUSED(result, result);
+ return jitCompileIfAppropriate(globalData, m_evalCodeBlock, m_jitCodeForCall, JITCode::bottomTierJIT(), JITCompilationCanFail);
}
#endif
@@ -210,8 +209,7 @@ JSObject* EvalExecutable::compileInternal(ExecState* exec, ScopeChainNode* scope
JSGlobalData* globalData = &exec->globalData();
JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
- if (!!m_evalCodeBlock && m_evalCodeBlock->canProduceCopyWithBytecode()) {
- BytecodeDestructionBlocker blocker(m_evalCodeBlock.get());
+ if (!!m_evalCodeBlock) {
OwnPtr<EvalCodeBlock> newCodeBlock = adoptPtr(new EvalCodeBlock(CodeBlock::CopyParsedBlock, *m_evalCodeBlock));
newCodeBlock->setAlternative(static_pointer_cast<CodeBlock>(m_evalCodeBlock.release()));
m_evalCodeBlock = newCodeBlock.release();
@@ -223,7 +221,7 @@ JSObject* EvalExecutable::compileInternal(ExecState* exec, ScopeChainNode* scope
ASSERT(exception);
return exception;
}
- recordParse(evalNode->features(), evalNode->hasCapturedVariables(), evalNode->lineNo(), evalNode->lastLine());
+ recordParse(evalNode->scopeFlags(), evalNode->hasCapturedVariables(), evalNode->lineNo(), evalNode->lastLine());
JSGlobalObject* globalObject = scopeChainNode->globalObject.get();
@@ -328,10 +326,9 @@ JSObject* ProgramExecutable::compileOptimized(ExecState* exec, ScopeChainNode* s
}
#if ENABLE(JIT)
-void ProgramExecutable::jitCompile(JSGlobalData& globalData)
+bool ProgramExecutable::jitCompile(JSGlobalData& globalData)
{
- bool result = jitCompileIfAppropriate(globalData, m_programCodeBlock, m_jitCodeForCall, JITCode::bottomTierJIT());
- ASSERT_UNUSED(result, result);
+ return jitCompileIfAppropriate(globalData, m_programCodeBlock, m_jitCodeForCall, JITCode::bottomTierJIT(), JITCompilationCanFail);
}
#endif
@@ -346,8 +343,7 @@ JSObject* ProgramExecutable::compileInternal(ExecState* exec, ScopeChainNode* sc
JSGlobalData* globalData = &exec->globalData();
JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
- if (!!m_programCodeBlock && m_programCodeBlock->canProduceCopyWithBytecode()) {
- BytecodeDestructionBlocker blocker(m_programCodeBlock.get());
+ if (!!m_programCodeBlock) {
OwnPtr<ProgramCodeBlock> newCodeBlock = adoptPtr(new ProgramCodeBlock(CodeBlock::CopyParsedBlock, *m_programCodeBlock));
newCodeBlock->setAlternative(static_pointer_cast<CodeBlock>(m_programCodeBlock.release()));
m_programCodeBlock = newCodeBlock.release();
@@ -357,7 +353,7 @@ JSObject* ProgramExecutable::compileInternal(ExecState* exec, ScopeChainNode* sc
ASSERT(exception);
return exception;
}
- recordParse(programNode->features(), programNode->hasCapturedVariables(), programNode->lineNo(), programNode->lastLine());
+ recordParse(programNode->scopeFlags(), programNode->hasCapturedVariables(), programNode->lineNo(), programNode->lastLine());
JSGlobalObject* globalObject = scopeChainNode->globalObject.get();
@@ -479,33 +475,26 @@ JSObject* FunctionExecutable::compileOptimizedForConstruct(ExecState* exec, Scop
}
#if ENABLE(JIT)
-void FunctionExecutable::jitCompileForCall(JSGlobalData& globalData)
+bool FunctionExecutable::jitCompileForCall(JSGlobalData& globalData)
{
- bool result = jitCompileFunctionIfAppropriate(globalData, m_codeBlockForCall, m_jitCodeForCall, m_jitCodeForCallWithArityCheck, m_symbolTable, JITCode::bottomTierJIT());
- ASSERT_UNUSED(result, result);
+ return jitCompileFunctionIfAppropriate(globalData, m_codeBlockForCall, m_jitCodeForCall, m_jitCodeForCallWithArityCheck, m_symbolTable, JITCode::bottomTierJIT(), JITCompilationCanFail);
}
-void FunctionExecutable::jitCompileForConstruct(JSGlobalData& globalData)
+bool FunctionExecutable::jitCompileForConstruct(JSGlobalData& globalData)
{
- bool result = jitCompileFunctionIfAppropriate(globalData, m_codeBlockForConstruct, m_jitCodeForConstruct, m_jitCodeForConstructWithArityCheck, m_symbolTable, JITCode::bottomTierJIT());
- ASSERT_UNUSED(result, result);
+ return jitCompileFunctionIfAppropriate(globalData, m_codeBlockForConstruct, m_jitCodeForConstruct, m_jitCodeForConstructWithArityCheck, m_symbolTable, JITCode::bottomTierJIT(), JITCompilationCanFail);
}
#endif
FunctionCodeBlock* FunctionExecutable::codeBlockWithBytecodeFor(CodeSpecializationKind kind)
{
- FunctionCodeBlock* codeBlock = baselineCodeBlockFor(kind);
- if (codeBlock->canProduceCopyWithBytecode())
- return codeBlock;
- return 0;
+ return baselineCodeBlockFor(kind);
}
PassOwnPtr<FunctionCodeBlock> FunctionExecutable::produceCodeBlockFor(ScopeChainNode* scopeChainNode, CompilationKind compilationKind, CodeSpecializationKind specializationKind, JSObject*& exception)
{
- if (!!codeBlockFor(specializationKind) && codeBlockFor(specializationKind)->canProduceCopyWithBytecode()) {
- BytecodeDestructionBlocker blocker(codeBlockFor(specializationKind).get());
+ if (!!codeBlockFor(specializationKind))
return adoptPtr(new FunctionCodeBlock(CodeBlock::CopyParsedBlock, *codeBlockFor(specializationKind)));
- }
exception = 0;
JSGlobalData* globalData = scopeChainNode->globalData;
@@ -519,7 +508,7 @@ PassOwnPtr<FunctionCodeBlock> FunctionExecutable::produceCodeBlockFor(ScopeChain
if (m_forceUsesArguments)
body->setUsesArguments();
body->finishParsing(m_parameters, m_name);
- recordParse(body->features(), body->hasCapturedVariables(), body->lineNo(), body->lastLine());
+ recordParse(body->scopeFlags(), body->hasCapturedVariables(), body->lineNo(), body->lastLine());
OwnPtr<FunctionCodeBlock> result;
ASSERT((compilationKind == FirstCompilation) == !codeBlockFor(specializationKind));
diff --git a/Source/JavaScriptCore/runtime/Executable.h b/Source/JavaScriptCore/runtime/Executable.h
index 69e80b28e..08b39fcf0 100644
--- a/Source/JavaScriptCore/runtime/Executable.h
+++ b/Source/JavaScriptCore/runtime/Executable.h
@@ -180,13 +180,14 @@ namespace JSC {
class NativeExecutable : public ExecutableBase {
friend class JIT;
+ friend class LLIntOffsetsExtractor;
public:
typedef ExecutableBase Base;
#if ENABLE(JIT)
static NativeExecutable* create(JSGlobalData& globalData, MacroAssemblerCodeRef callThunk, NativeFunction function, MacroAssemblerCodeRef constructThunk, NativeFunction constructor, Intrinsic intrinsic)
{
- ASSERT(globalData.canUseJIT());
+ ASSERT(!globalData.interpreter->classicEnabled());
NativeExecutable* executable;
if (!callThunk) {
executable = new (NotNull, allocateCell<NativeExecutable>(globalData.heap)) NativeExecutable(globalData, function, constructor);
@@ -228,7 +229,7 @@ namespace JSC {
#if ENABLE(JIT)
void finishCreation(JSGlobalData& globalData, JITCode callThunk, JITCode constructThunk, Intrinsic intrinsic)
{
- ASSERT(globalData.canUseJIT());
+ ASSERT(!globalData.interpreter->classicEnabled());
Base::finishCreation(globalData);
m_jitCodeForCall = callThunk;
m_jitCodeForConstruct = constructThunk;
@@ -270,14 +271,14 @@ namespace JSC {
ScriptExecutable(Structure* structure, JSGlobalData& globalData, const SourceCode& source, bool isInStrictContext)
: ExecutableBase(globalData, structure, NUM_PARAMETERS_NOT_COMPILED)
, m_source(source)
- , m_features(isInStrictContext ? StrictModeFeature : 0)
+ , m_scopeFlags(isInStrictContext ? StrictModeFlag : NoScopeFlags)
{
}
ScriptExecutable(Structure* structure, ExecState* exec, const SourceCode& source, bool isInStrictContext)
: ExecutableBase(exec->globalData(), structure, NUM_PARAMETERS_NOT_COMPILED)
, m_source(source)
- , m_features(isInStrictContext ? StrictModeFeature : 0)
+ , m_scopeFlags(isInStrictContext ? StrictModeFlag : NoScopeFlags)
{
}
@@ -291,10 +292,10 @@ namespace JSC {
int lineNo() const { return m_firstLine; }
int lastLine() const { return m_lastLine; }
- bool usesEval() const { return m_features & EvalFeature; }
- bool usesArguments() const { return m_features & ArgumentsFeature; }
- bool needsActivation() const { return m_hasCapturedVariables || m_features & (EvalFeature | WithFeature | CatchFeature); }
- bool isStrictMode() const { return m_features & StrictModeFeature; }
+ bool usesEval() const { return m_scopeFlags & UsesEvalFlag; }
+ bool usesArguments() const { return m_scopeFlags & UsesArgumentsFlag; }
+ bool needsActivation() const { return m_hasCapturedVariables || m_scopeFlags & (UsesEvalFlag | UsesWithFlag | UsesCatchFlag); }
+ bool isStrictMode() const { return m_scopeFlags & StrictModeFlag; }
void unlinkCalls();
@@ -310,16 +311,16 @@ namespace JSC {
#endif
}
- void recordParse(CodeFeatures features, bool hasCapturedVariables, int firstLine, int lastLine)
+ void recordParse(ScopeFlags scopeFlags, bool hasCapturedVariables, int firstLine, int lastLine)
{
- m_features = features;
+ m_scopeFlags = scopeFlags;
m_hasCapturedVariables = hasCapturedVariables;
m_firstLine = firstLine;
m_lastLine = lastLine;
}
SourceCode m_source;
- CodeFeatures m_features;
+ ScopeFlags m_scopeFlags;
bool m_hasCapturedVariables;
int m_firstLine;
int m_lastLine;
@@ -346,7 +347,7 @@ namespace JSC {
#if ENABLE(JIT)
void jettisonOptimizedCode(JSGlobalData&);
- void jitCompile(JSGlobalData&);
+ bool jitCompile(JSGlobalData&);
#endif
EvalCodeBlock& generatedBytecode()
@@ -421,7 +422,7 @@ namespace JSC {
#if ENABLE(JIT)
void jettisonOptimizedCode(JSGlobalData&);
- void jitCompile(JSGlobalData&);
+ bool jitCompile(JSGlobalData&);
#endif
ProgramCodeBlock& generatedBytecode()
@@ -520,7 +521,7 @@ namespace JSC {
#if ENABLE(JIT)
void jettisonOptimizedCodeForCall(JSGlobalData&);
- void jitCompileForCall(JSGlobalData&);
+ bool jitCompileForCall(JSGlobalData&);
#endif
bool isGeneratedForCall() const
@@ -548,7 +549,7 @@ namespace JSC {
#if ENABLE(JIT)
void jettisonOptimizedCodeForConstruct(JSGlobalData&);
- void jitCompileForConstruct(JSGlobalData&);
+ bool jitCompileForConstruct(JSGlobalData&);
#endif
bool isGeneratedForConstruct() const
@@ -597,14 +598,12 @@ namespace JSC {
}
}
- void jitCompileFor(JSGlobalData& globalData, CodeSpecializationKind kind)
+ bool jitCompileFor(JSGlobalData& globalData, CodeSpecializationKind kind)
{
- if (kind == CodeForCall) {
- jitCompileForCall(globalData);
- return;
- }
+ if (kind == CodeForCall)
+ return jitCompileForCall(globalData);
ASSERT(kind == CodeForConstruct);
- jitCompileForConstruct(globalData);
+ return jitCompileForConstruct(globalData);
}
#endif
diff --git a/Source/JavaScriptCore/runtime/ExecutionHarness.h b/Source/JavaScriptCore/runtime/ExecutionHarness.h
index 774c5bf6b..e58e6fc74 100644
--- a/Source/JavaScriptCore/runtime/ExecutionHarness.h
+++ b/Source/JavaScriptCore/runtime/ExecutionHarness.h
@@ -46,7 +46,7 @@ inline bool prepareForExecution(JSGlobalData& globalData, OwnPtr<CodeBlockType>&
return true;
}
#endif // ENABLE(LLINT)
- return jitCompileIfAppropriate(globalData, codeBlock, jitCode, jitType);
+ return jitCompileIfAppropriate(globalData, codeBlock, jitCode, jitType, JITCode::isBaselineCode(jitType) ? JITCompilationMustSucceed : JITCompilationCanFail);
}
inline bool prepareFunctionForExecution(JSGlobalData& globalData, OwnPtr<FunctionCodeBlock>& codeBlock, JITCode& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck, SharedSymbolTable*& symbolTable, JITCode::JITType jitType, CodeSpecializationKind kind)
@@ -61,7 +61,7 @@ inline bool prepareFunctionForExecution(JSGlobalData& globalData, OwnPtr<Functio
#else
UNUSED_PARAM(kind);
#endif // ENABLE(LLINT)
- return jitCompileFunctionIfAppropriate(globalData, codeBlock, jitCode, jitCodeWithArityCheck, symbolTable, jitType);
+ return jitCompileFunctionIfAppropriate(globalData, codeBlock, jitCode, jitCodeWithArityCheck, symbolTable, jitType, JITCode::isBaselineCode(jitType) ? JITCompilationMustSucceed : JITCompilationCanFail);
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/GCActivityCallbackCF.cpp b/Source/JavaScriptCore/runtime/GCActivityCallbackCF.cpp
index 2e878bfe3..7f45f0746 100644
--- a/Source/JavaScriptCore/runtime/GCActivityCallbackCF.cpp
+++ b/Source/JavaScriptCore/runtime/GCActivityCallbackCF.cpp
@@ -53,7 +53,6 @@ struct DefaultGCActivityCallbackPlatformData {
};
const CFTimeInterval decade = 60 * 60 * 24 * 365 * 10;
-const CFTimeInterval triggerInterval = 2; // seconds
void DefaultGCActivityCallbackPlatformData::trigger(CFRunLoopTimerRef timer, void *info)
{
@@ -95,6 +94,7 @@ void DefaultGCActivityCallback::commonConstructor(Heap* heap, CFRunLoopRef runLo
void DefaultGCActivityCallback::operator()()
{
+ CFTimeInterval triggerInterval = static_cast<Heap*>(d->context.info)->lastGCLength() * 100.0;
CFRunLoopTimerSetNextFireDate(d->timer.get(), CFAbsoluteTimeGetCurrent() + triggerInterval);
}
diff --git a/Source/JavaScriptCore/runtime/Identifier.cpp b/Source/JavaScriptCore/runtime/Identifier.cpp
index 0d233e355..fbc5787ce 100644
--- a/Source/JavaScriptCore/runtime/Identifier.cpp
+++ b/Source/JavaScriptCore/runtime/Identifier.cpp
@@ -36,20 +36,6 @@ using WTF::ThreadSpecific;
namespace JSC {
-IdentifierTable::~IdentifierTable()
-{
- HashSet<StringImpl*>::iterator end = m_table.end();
- for (HashSet<StringImpl*>::iterator iter = m_table.begin(); iter != end; ++iter)
- (*iter)->setIsIdentifier(false);
-}
-
-std::pair<HashSet<StringImpl*>::iterator, bool> IdentifierTable::add(StringImpl* value)
-{
- std::pair<HashSet<StringImpl*>::iterator, bool> result = m_table.add(value);
- (*result.first)->setIsIdentifier(true);
- return result;
-}
-
IdentifierTable* createIdentifierTable()
{
return new IdentifierTable;
diff --git a/Source/JavaScriptCore/runtime/Identifier.h b/Source/JavaScriptCore/runtime/Identifier.h
index 947c95b33..b9e5a1854 100644
--- a/Source/JavaScriptCore/runtime/Identifier.h
+++ b/Source/JavaScriptCore/runtime/Identifier.h
@@ -22,7 +22,7 @@
#define Identifier_h
#include "JSGlobalData.h"
-#include "ThreadSpecific.h"
+#include <wtf/ThreadSpecific.h>
#include "UString.h"
#include <wtf/WTFThreadData.h>
#include <wtf/text/CString.h>
diff --git a/Source/JavaScriptCore/runtime/InitializeThreading.cpp b/Source/JavaScriptCore/runtime/InitializeThreading.cpp
index 2b874c708..b6fd6ce1f 100644
--- a/Source/JavaScriptCore/runtime/InitializeThreading.cpp
+++ b/Source/JavaScriptCore/runtime/InitializeThreading.cpp
@@ -37,7 +37,7 @@
#include "JSGlobalObject.h"
#include "UString.h"
#include "WriteBarrier.h"
-#include "dtoa.h"
+#include <wtf/dtoa.h>
#include <wtf/Threading.h>
#include <wtf/dtoa/cached-powers.h>
diff --git a/Source/JavaScriptCore/runtime/JSArray.cpp b/Source/JavaScriptCore/runtime/JSArray.cpp
index 71d520018..4244bc31c 100644
--- a/Source/JavaScriptCore/runtime/JSArray.cpp
+++ b/Source/JavaScriptCore/runtime/JSArray.cpp
@@ -41,6 +41,7 @@ using namespace WTF;
namespace JSC {
+
ASSERT_CLASS_FITS_IN_CELL(JSArray);
ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSArray);
@@ -104,23 +105,16 @@ const ClassInfo JSArray::s_info = {"Array", &JSNonFinalObject::s_info, 0, 0, CRE
// This value is capped by the constant FIRST_VECTOR_GROW defined above.
static unsigned lastArraySize = 0;
-static inline size_t storageSize(unsigned vectorLength)
+static inline bool isDenseEnoughForVector(unsigned length, unsigned numValues)
{
- ASSERT(vectorLength <= MAX_STORAGE_VECTOR_LENGTH);
-
- // MAX_STORAGE_VECTOR_LENGTH is defined such that provided (vectorLength <= MAX_STORAGE_VECTOR_LENGTH)
- // - as asserted above - the following calculation cannot overflow.
- size_t size = (sizeof(ArrayStorage) - sizeof(WriteBarrier<Unknown>)) + (vectorLength * sizeof(WriteBarrier<Unknown>));
- // Assertion to detect integer overflow in previous calculation (should not be possible, provided that
- // MAX_STORAGE_VECTOR_LENGTH is correctly defined).
- ASSERT(((size - (sizeof(ArrayStorage) - sizeof(WriteBarrier<Unknown>))) / sizeof(WriteBarrier<Unknown>) == vectorLength) && (size >= (sizeof(ArrayStorage) - sizeof(WriteBarrier<Unknown>))));
-
- return size;
+ return length <= MIN_SPARSE_ARRAY_INDEX || length / minDensityMultiplier <= numValues;
}
-static inline bool isDenseEnoughForVector(unsigned length, unsigned numValues)
+static bool reject(ExecState* exec, bool throwException, const char* message)
{
- return length <= MIN_SPARSE_ARRAY_INDEX || length / minDensityMultiplier <= numValues;
+ if (throwException)
+ throwTypeError(exec, message);
+ return false;
}
#if !CHECK_ARRAY_CONSISTENCY
@@ -213,7 +207,7 @@ inline std::pair<SparseArrayValueMap::iterator, bool> SparseArrayValueMap::add(J
return result;
}
-inline void SparseArrayValueMap::put(ExecState* exec, JSArray* array, unsigned i, JSValue value)
+inline void SparseArrayValueMap::put(ExecState* exec, JSArray* array, unsigned i, JSValue value, bool shouldThrow)
{
std::pair<SparseArrayValueMap::iterator, bool> result = add(array, i);
SparseArrayEntry& entry = result.first->second;
@@ -223,14 +217,15 @@ inline void SparseArrayValueMap::put(ExecState* exec, JSArray* array, unsigned i
// extensible, this is not the right thing to have done - so remove again.
if (result.second && !array->isExtensible()) {
remove(result.first);
- // FIXME: should throw in strict mode.
+ if (shouldThrow)
+ throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
return;
}
if (!(entry.attributes & Accessor)) {
if (entry.attributes & ReadOnly) {
- // FIXME: should throw if being called from strict mode.
- // throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
+ if (shouldThrow)
+ throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
return;
}
@@ -243,8 +238,8 @@ inline void SparseArrayValueMap::put(ExecState* exec, JSArray* array, unsigned i
JSObject* setter = asGetterSetter(accessor)->setter();
if (!setter) {
- // FIXME: should throw if being called from strict mode.
- // throwTypeError(exec, "setting a property that has only a getter");
+ if (shouldThrow)
+ throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
return;
}
@@ -255,6 +250,24 @@ inline void SparseArrayValueMap::put(ExecState* exec, JSArray* array, unsigned i
call(exec, setter, callType, callData, array, args);
}
+inline bool SparseArrayValueMap::putDirect(ExecState* exec, JSArray* array, unsigned i, JSValue value, bool shouldThrow)
+{
+ std::pair<SparseArrayValueMap::iterator, bool> result = add(array, i);
+ SparseArrayEntry& entry = result.first->second;
+
+ // To save a separate find & add, we first always add to the sparse map.
+ // In the uncommon case that this is a new property, and the array is not
+ // extensible, this is not the right thing to have done - so remove again.
+ if (result.second && !array->isExtensible()) {
+ remove(result.first);
+ return reject(exec, shouldThrow, "Attempting to define property on object that is not extensible.");
+ }
+
+ entry.attributes = 0;
+ entry.set(exec->globalData(), array, value);
+ return true;
+}
+
inline void SparseArrayEntry::get(PropertySlot& slot) const
{
JSValue value = Base::get();
@@ -395,13 +408,6 @@ void JSArray::putDescriptor(ExecState* exec, SparseArrayEntry* entryInMap, Prope
entryInMap->attributes = descriptor.attributesOverridingCurrent(oldDescriptor);
}
-static bool reject(ExecState* exec, bool throwException, const char* message)
-{
- if (throwException)
- throwTypeError(exec, message);
- return false;
-}
-
// Defined in ES5.1 8.12.9
bool JSArray::defineOwnNumericProperty(ExecState* exec, unsigned index, PropertyDescriptor& descriptor, bool throwException)
{
@@ -414,8 +420,7 @@ bool JSArray::defineOwnNumericProperty(ExecState* exec, unsigned index, Property
// state (i.e. defineOwnProperty could be used to set a value without needing to entering 'SparseMode').
if (!descriptor.attributes()) {
ASSERT(!descriptor.isAccessorDescriptor());
- putByIndex(this, exec, index, descriptor.value());
- return true;
+ return putDirectIndex(exec, index, descriptor.value(), throwException);
}
enterDictionaryMode(exec->globalData());
@@ -721,7 +726,7 @@ void JSArray::put(JSCell* cell, ExecState* exec, const Identifier& propertyName,
bool isArrayIndex;
unsigned i = propertyName.toArrayIndex(isArrayIndex);
if (isArrayIndex) {
- putByIndex(thisObject, exec, i, value);
+ putByIndex(thisObject, exec, i, value, slot.isStrictMode());
return;
}
@@ -738,7 +743,7 @@ void JSArray::put(JSCell* cell, ExecState* exec, const Identifier& propertyName,
JSObject::put(thisObject, exec, propertyName, value, slot);
}
-void JSArray::putByIndex(JSCell* cell, ExecState* exec, unsigned i, JSValue value)
+void JSArray::putByIndex(JSCell* cell, ExecState* exec, unsigned i, JSValue value, bool shouldThrow)
{
JSArray* thisObject = jsCast<JSArray*>(cell);
thisObject->checkConsistency();
@@ -765,17 +770,17 @@ void JSArray::putByIndex(JSCell* cell, ExecState* exec, unsigned i, JSValue valu
// Handle 2^32-1 - this is not an array index (see ES5.1 15.4), and is treated as a regular property.
if (UNLIKELY(i > MAX_ARRAY_INDEX)) {
- PutPropertySlot slot;
+ PutPropertySlot slot(shouldThrow);
thisObject->methodTable()->put(thisObject, exec, Identifier::from(exec, i), value, slot);
return;
}
// For all other cases, call putByIndexBeyondVectorLength.
- thisObject->putByIndexBeyondVectorLength(exec, i, value);
+ thisObject->putByIndexBeyondVectorLength(exec, i, value, shouldThrow);
thisObject->checkConsistency();
}
-NEVER_INLINE void JSArray::putByIndexBeyondVectorLength(ExecState* exec, unsigned i, JSValue value)
+void JSArray::putByIndexBeyondVectorLength(ExecState* exec, unsigned i, JSValue value, bool shouldThrow)
{
JSGlobalData& globalData = exec->globalData();
@@ -806,7 +811,7 @@ NEVER_INLINE void JSArray::putByIndexBeyondVectorLength(ExecState* exec, unsigne
// We don't want to, or can't use a vector to hold this property - allocate a sparse map & add the value.
allocateSparseMap(exec->globalData());
map = m_sparseValueMap;
- map->put(exec, this, i, value);
+ map->put(exec, this, i, value, shouldThrow);
return;
}
@@ -815,7 +820,8 @@ NEVER_INLINE void JSArray::putByIndexBeyondVectorLength(ExecState* exec, unsigne
if (i >= length) {
// Prohibit growing the array if length is not writable.
if (map->lengthIsReadOnly() || !isExtensible()) {
- // FIXME: should throw in strict mode.
+ if (shouldThrow)
+ throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
return;
}
length = i + 1;
@@ -826,7 +832,7 @@ NEVER_INLINE void JSArray::putByIndexBeyondVectorLength(ExecState* exec, unsigne
// We will continue to use a sparse map if SparseMode is set, a vector would be too sparse, or if allocation fails.
unsigned numValuesInArray = storage->m_numValuesInVector + map->size();
if (map->sparseMode() || !isDenseEnoughForVector(length, numValuesInArray) || !increaseVectorLength(exec->globalData(), length)) {
- map->put(exec, this, i, value);
+ map->put(exec, this, i, value, shouldThrow);
return;
}
@@ -848,6 +854,77 @@ NEVER_INLINE void JSArray::putByIndexBeyondVectorLength(ExecState* exec, unsigne
valueSlot.set(globalData, this, value);
}
+bool JSArray::putDirectIndexBeyondVectorLength(ExecState* exec, unsigned i, JSValue value, bool shouldThrow)
+{
+ JSGlobalData& globalData = exec->globalData();
+
+ // i should be a valid array index that is outside of the current vector.
+ ASSERT(i >= m_vectorLength);
+ ASSERT(i <= MAX_ARRAY_INDEX);
+
+ ArrayStorage* storage = m_storage;
+ SparseArrayValueMap* map = m_sparseValueMap;
+
+ // First, handle cases where we don't currently have a sparse map.
+ if (LIKELY(!map)) {
+ // If the array is not extensible, we should have entered dictionary mode, and created the spare map.
+ ASSERT(isExtensible());
+
+ // Update m_length if necessary.
+ if (i >= storage->m_length)
+ storage->m_length = i + 1;
+
+ // Check that it is sensible to still be using a vector, and then try to grow the vector.
+ if (LIKELY((isDenseEnoughForVector(i, storage->m_numValuesInVector)) && increaseVectorLength(globalData, i + 1))) {
+ // success! - reread m_storage since it has likely been reallocated, and store to the vector.
+ storage = m_storage;
+ storage->m_vector[i].set(globalData, this, value);
+ ++storage->m_numValuesInVector;
+ return true;
+ }
+ // We don't want to, or can't use a vector to hold this property - allocate a sparse map & add the value.
+ allocateSparseMap(exec->globalData());
+ map = m_sparseValueMap;
+ return map->putDirect(exec, this, i, value, shouldThrow);
+ }
+
+ // Update m_length if necessary.
+ unsigned length = storage->m_length;
+ if (i >= length) {
+ // Prohibit growing the array if length is not writable.
+ if (map->lengthIsReadOnly())
+ return reject(exec, shouldThrow, StrictModeReadonlyPropertyWriteError);
+ if (!isExtensible())
+ return reject(exec, shouldThrow, "Attempting to define property on object that is not extensible.");
+ length = i + 1;
+ storage->m_length = length;
+ }
+
+ // We are currently using a map - check whether we still want to be doing so.
+ // We will continue to use a sparse map if SparseMode is set, a vector would be too sparse, or if allocation fails.
+ unsigned numValuesInArray = storage->m_numValuesInVector + map->size();
+ if (map->sparseMode() || !isDenseEnoughForVector(length, numValuesInArray) || !increaseVectorLength(exec->globalData(), length))
+ return map->putDirect(exec, this, i, value, shouldThrow);
+
+ // Reread m_storage afterincreaseVectorLength, update m_numValuesInVector.
+ storage = m_storage;
+ storage->m_numValuesInVector = numValuesInArray;
+
+ // Copy all values from the map into the vector, and delete the map.
+ WriteBarrier<Unknown>* vector = storage->m_vector;
+ SparseArrayValueMap::const_iterator end = map->end();
+ for (SparseArrayValueMap::const_iterator it = map->begin(); it != end; ++it)
+ vector[it->first].set(globalData, this, it->second.getNonSparseMode());
+ deallocateSparseMap();
+
+ // Store the new property into the vector.
+ WriteBarrier<Unknown>& valueSlot = vector[i];
+ if (!valueSlot)
+ ++storage->m_numValuesInVector;
+ valueSlot.set(globalData, this, value);
+ return true;
+}
+
bool JSArray::deleteProperty(JSCell* cell, ExecState* exec, const Identifier& propertyName)
{
JSArray* thisObject = jsCast<JSArray*>(cell);
@@ -1220,18 +1297,19 @@ void JSArray::push(ExecState* exec, JSValue value)
// Pushing to an array of length 2^32-1 stores the property, but throws a range error.
if (UNLIKELY(storage->m_length == 0xFFFFFFFFu)) {
- methodTable()->putByIndex(this, exec, storage->m_length, value);
+ methodTable()->putByIndex(this, exec, storage->m_length, value, true);
// Per ES5.1 15.4.4.7 step 6 & 15.4.5.1 step 3.d.
- throwError(exec, createRangeError(exec, "Invalid array length"));
+ if (!exec->hadException())
+ throwError(exec, createRangeError(exec, "Invalid array length"));
return;
}
// Handled the same as putIndex.
- putByIndexBeyondVectorLength(exec, storage->m_length, value);
+ putByIndexBeyondVectorLength(exec, storage->m_length, value, true);
checkConsistency();
}
-void JSArray::shiftCount(ExecState* exec, unsigned count)
+bool JSArray::shiftCount(ExecState*, unsigned count)
{
ASSERT(count > 0);
@@ -1239,32 +1317,15 @@ void JSArray::shiftCount(ExecState* exec, unsigned count)
unsigned oldLength = storage->m_length;
- if (!oldLength)
- return;
-
- if (oldLength != storage->m_numValuesInVector) {
- // If m_length and m_numValuesInVector aren't the same, we have a sparse vector
- // which means we need to go through each entry looking for the the "empty"
- // slots and then fill them with possible properties. See ECMA spec.
- // 15.4.4.9 steps 11 through 13.
- for (unsigned i = count; i < oldLength; ++i) {
- if ((i >= m_vectorLength) || (!m_storage->m_vector[i])) {
- PropertySlot slot(this);
- JSValue p = prototype();
- if ((!p.isNull()) && (asObject(p)->getPropertySlot(exec, i, slot)))
- methodTable()->putByIndex(this, exec, i, slot.getValue(exec, i));
- }
- }
-
- storage = m_storage; // The put() above could have grown the vector and realloc'ed storage.
+ // If the array contains holes or is otherwise in an abnormal state,
+ // use the generic algorithm in ArrayPrototype.
+ if (oldLength != storage->m_numValuesInVector || inSparseMode())
+ return false;
- // Need to decrement numValuesInvector based on number of real entries
- for (unsigned i = 0; i < (unsigned)count; ++i)
- if ((i < m_vectorLength) && (storage->m_vector[i]))
- --storage->m_numValuesInVector;
- } else
- storage->m_numValuesInVector -= count;
+ if (!oldLength)
+ return true;
+ storage->m_numValuesInVector -= count;
storage->m_length -= count;
if (m_vectorLength) {
@@ -1280,30 +1341,20 @@ void JSArray::shiftCount(ExecState* exec, unsigned count)
m_indexBias += count;
}
}
+ return true;
}
-
-void JSArray::unshiftCount(ExecState* exec, unsigned count)
+
+// Returns true if the unshift can be handled, false to fallback.
+bool JSArray::unshiftCount(ExecState* exec, unsigned count)
{
ArrayStorage* storage = m_storage;
unsigned length = storage->m_length;
- if (length != storage->m_numValuesInVector) {
- // If m_length and m_numValuesInVector aren't the same, we have a sparse vector
- // which means we need to go through each entry looking for the the "empty"
- // slots and then fill them with possible properties. See ECMA spec.
- // 15.4.4.13 steps 8 through 10.
- for (unsigned i = 0; i < length; ++i) {
- if ((i >= m_vectorLength) || (!m_storage->m_vector[i])) {
- PropertySlot slot(this);
- JSValue p = prototype();
- if ((!p.isNull()) && (asObject(p)->getPropertySlot(exec, i, slot)))
- methodTable()->putByIndex(this, exec, i, slot.getValue(exec, i));
- }
- }
- }
-
- storage = m_storage; // The put() above could have grown the vector and realloc'ed storage.
-
+ // If the array contains holes or is otherwise in an abnormal state,
+ // use the generic algorithm in ArrayPrototype.
+ if (length != storage->m_numValuesInVector || inSparseMode())
+ return false;
+
if (m_indexBias >= count) {
m_indexBias -= count;
char* newBaseStorage = reinterpret_cast<char*>(storage) - count * sizeof(WriteBarrier<Unknown>);
@@ -1312,12 +1363,13 @@ void JSArray::unshiftCount(ExecState* exec, unsigned count)
m_vectorLength += count;
} else if (!unshiftCountSlowCase(exec->globalData(), count)) {
throwOutOfMemoryError(exec);
- return;
+ return true;
}
WriteBarrier<Unknown>* vector = m_storage->m_vector;
for (unsigned i = 0; i < count; i++)
vector[i].clear();
+ return true;
}
void JSArray::visitChildren(JSCell* cell, SlotVisitor& visitor)
diff --git a/Source/JavaScriptCore/runtime/JSArray.h b/Source/JavaScriptCore/runtime/JSArray.h
index 3bb4c6320..ad98d6619 100644
--- a/Source/JavaScriptCore/runtime/JSArray.h
+++ b/Source/JavaScriptCore/runtime/JSArray.h
@@ -85,7 +85,8 @@ namespace JSC {
}
// These methods may mutate the contents of the map
- void put(ExecState*, JSArray*, unsigned, JSValue);
+ void put(ExecState*, JSArray*, unsigned, JSValue, bool shouldThrow);
+ bool putDirect(ExecState*, JSArray*, unsigned, JSValue, bool shouldThrow);
std::pair<iterator, bool> add(JSArray*, unsigned);
iterator find(unsigned i) { return m_map.find(i); }
// This should ASSERT the remove is valid (check the result of the find).
@@ -122,11 +123,17 @@ namespace JSC {
uintptr_t m_padding;
#endif
WriteBarrier<Unknown> m_vector[1];
+
+ static ptrdiff_t lengthOffset() { return OBJECT_OFFSETOF(ArrayStorage, m_length); }
+ static ptrdiff_t numValuesInVectorOffset() { return OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector); }
+ static ptrdiff_t allocBaseOffset() { return OBJECT_OFFSETOF(ArrayStorage, m_allocBase); }
+ static ptrdiff_t vectorOffset() { return OBJECT_OFFSETOF(ArrayStorage, m_vector); }
};
class JSArray : public JSNonFinalObject {
friend class LLIntOffsetsExtractor;
friend class Walker;
+ friend class JIT;
protected:
JS_EXPORT_PRIVATE explicit JSArray(JSGlobalData&, Structure*);
@@ -153,7 +160,19 @@ namespace JSC {
static bool getOwnPropertySlot(JSCell*, ExecState*, const Identifier&, PropertySlot&);
JS_EXPORT_PRIVATE static bool getOwnPropertySlotByIndex(JSCell*, ExecState*, unsigned propertyName, PropertySlot&);
static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
- static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue);
+ static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
+ // This is similar to the JSObject::putDirect* methods:
+ // - the prototype chain is not consulted
+ // - accessors are not called.
+ // This method creates a property with attributes writable, enumerable and configurable all set to true.
+ bool putDirectIndex(ExecState* exec, unsigned propertyName, JSValue value, bool shouldThrow = true)
+ {
+ if (canSetIndex(propertyName)) {
+ setIndex(exec->globalData(), propertyName, value);
+ return true;
+ }
+ return putDirectIndexBeyondVectorLength(exec, propertyName, value, shouldThrow);
+ }
static JS_EXPORTDATA const ClassInfo s_info;
@@ -168,8 +187,8 @@ namespace JSC {
void push(ExecState*, JSValue);
JSValue pop(ExecState*);
- void shiftCount(ExecState*, unsigned count);
- void unshiftCount(ExecState*, unsigned count);
+ bool shiftCount(ExecState*, unsigned count);
+ bool unshiftCount(ExecState*, unsigned count);
bool canGetIndex(unsigned i) { return i < m_vectorLength && m_storage->m_vector[i]; }
JSValue getIndex(unsigned i)
@@ -262,6 +281,7 @@ namespace JSC {
JS_EXPORT_PRIVATE void setSubclassData(void*);
private:
+ static size_t storageSize(unsigned vectorLength);
bool isLengthWritable()
{
SparseArrayValueMap* map = m_sparseValueMap;
@@ -275,7 +295,8 @@ namespace JSC {
void deallocateSparseMap();
bool getOwnPropertySlotSlowCase(ExecState*, unsigned propertyName, PropertySlot&);
- void putByIndexBeyondVectorLength(ExecState*, unsigned propertyName, JSValue);
+ void putByIndexBeyondVectorLength(ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
+ JS_EXPORT_PRIVATE bool putDirectIndexBeyondVectorLength(ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
unsigned getNewVectorLength(unsigned desiredLength);
bool increaseVectorLength(JSGlobalData&, unsigned newLength);
@@ -293,6 +314,10 @@ namespace JSC {
// FIXME: Maybe SparseArrayValueMap should be put into its own JSCell?
SparseArrayValueMap* m_sparseValueMap;
void* m_subclassData; // A JSArray subclass can use this to fill the vector lazily.
+
+ static ptrdiff_t sparseValueMapOffset() { return OBJECT_OFFSETOF(JSArray, m_sparseValueMap); }
+ static ptrdiff_t subclassDataOffset() { return OBJECT_OFFSETOF(JSArray, m_subclassData); }
+ static ptrdiff_t indexBiasOffset() { return OBJECT_OFFSETOF(JSArray, m_indexBias); }
};
inline JSArray* JSArray::create(JSGlobalData& globalData, Structure* structure, unsigned initialLength)
@@ -334,6 +359,30 @@ namespace JSC {
return i;
}
-} // namespace JSC
+// The definition of MAX_STORAGE_VECTOR_LENGTH is dependant on the definition storageSize
+// function below - the MAX_STORAGE_VECTOR_LENGTH limit is defined such that the storage
+// size calculation cannot overflow. (sizeof(ArrayStorage) - sizeof(WriteBarrier<Unknown>)) +
+// (vectorLength * sizeof(WriteBarrier<Unknown>)) must be <= 0xFFFFFFFFU (which is maximum value of size_t).
+#define MAX_STORAGE_VECTOR_LENGTH static_cast<unsigned>((0xFFFFFFFFU - (sizeof(ArrayStorage) - sizeof(WriteBarrier<Unknown>))) / sizeof(WriteBarrier<Unknown>))
+
+// 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>.
+#define MIN_SPARSE_ARRAY_INDEX 10000U
+#define MAX_STORAGE_VECTOR_INDEX (MAX_STORAGE_VECTOR_LENGTH - 1)
+ inline size_t JSArray::storageSize(unsigned vectorLength)
+ {
+ ASSERT(vectorLength <= MAX_STORAGE_VECTOR_LENGTH);
+
+ // MAX_STORAGE_VECTOR_LENGTH is defined such that provided (vectorLength <= MAX_STORAGE_VECTOR_LENGTH)
+ // - as asserted above - the following calculation cannot overflow.
+ size_t size = (sizeof(ArrayStorage) - sizeof(WriteBarrier<Unknown>)) + (vectorLength * sizeof(WriteBarrier<Unknown>));
+ // Assertion to detect integer overflow in previous calculation (should not be possible, provided that
+ // MAX_STORAGE_VECTOR_LENGTH is correctly defined).
+ ASSERT(((size - (sizeof(ArrayStorage) - sizeof(WriteBarrier<Unknown>))) / sizeof(WriteBarrier<Unknown>) == vectorLength) && (size >= (sizeof(ArrayStorage) - sizeof(WriteBarrier<Unknown>))));
+
+ return size;
+ }
+
+ } // namespace JSC
#endif // JSArray_h
diff --git a/Source/JavaScriptCore/runtime/JSByteArray.cpp b/Source/JavaScriptCore/runtime/JSByteArray.cpp
index 3df21e6f5..39ea4d0b9 100644
--- a/Source/JavaScriptCore/runtime/JSByteArray.cpp
+++ b/Source/JavaScriptCore/runtime/JSByteArray.cpp
@@ -102,7 +102,7 @@ void JSByteArray::put(JSCell* cell, ExecState* exec, const Identifier& propertyN
JSObject::put(thisObject, exec, propertyName, value, slot);
}
-void JSByteArray::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue value)
+void JSByteArray::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue value, bool)
{
jsCast<JSByteArray*>(cell)->setIndex(exec, propertyName, value);
}
diff --git a/Source/JavaScriptCore/runtime/JSByteArray.h b/Source/JavaScriptCore/runtime/JSByteArray.h
index d1f4ad630..06181d901 100644
--- a/Source/JavaScriptCore/runtime/JSByteArray.h
+++ b/Source/JavaScriptCore/runtime/JSByteArray.h
@@ -92,7 +92,7 @@ namespace JSC {
JS_EXPORT_PRIVATE static bool getOwnPropertySlotByIndex(JSC::JSCell*, JSC::ExecState*, unsigned propertyName, JSC::PropertySlot&);
JS_EXPORT_PRIVATE static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
JS_EXPORT_PRIVATE static void put(JSC::JSCell*, JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&);
- JS_EXPORT_PRIVATE static void putByIndex(JSC::JSCell*, JSC::ExecState*, unsigned propertyName, JSC::JSValue);
+ JS_EXPORT_PRIVATE static void putByIndex(JSC::JSCell*, JSC::ExecState*, unsigned propertyName, JSC::JSValue, bool shouldThrow);
JS_EXPORT_PRIVATE static void getOwnPropertyNames(JSC::JSObject*, JSC::ExecState*, JSC::PropertyNameArray&, EnumerationMode);
diff --git a/Source/JavaScriptCore/runtime/JSCell.cpp b/Source/JavaScriptCore/runtime/JSCell.cpp
index 4703b681b..f08d0260a 100644
--- a/Source/JavaScriptCore/runtime/JSCell.cpp
+++ b/Source/JavaScriptCore/runtime/JSCell.cpp
@@ -97,14 +97,23 @@ bool JSCell::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigned i
void JSCell::put(JSCell* cell, ExecState* exec, const Identifier& identifier, JSValue value, PutPropertySlot& slot)
{
+ if (cell->isString()) {
+ JSValue(cell).putToPrimitive(exec, identifier, value, slot);
+ return;
+ }
JSObject* thisObject = cell->toObject(exec, exec->lexicalGlobalObject());
thisObject->methodTable()->put(thisObject, exec, identifier, value, slot);
}
-void JSCell::putByIndex(JSCell* cell, ExecState* exec, unsigned identifier, JSValue value)
+void JSCell::putByIndex(JSCell* cell, ExecState* exec, unsigned identifier, JSValue value, bool shouldThrow)
{
+ if (cell->isString()) {
+ PutPropertySlot slot(shouldThrow);
+ JSValue(cell).putToPrimitive(exec, Identifier::from(exec, identifier), value, slot);
+ return;
+ }
JSObject* thisObject = cell->toObject(exec, exec->lexicalGlobalObject());
- thisObject->methodTable()->putByIndex(thisObject, exec, identifier, value);
+ thisObject->methodTable()->putByIndex(thisObject, exec, identifier, value, shouldThrow);
}
bool JSCell::deleteProperty(JSCell* cell, ExecState* exec, const Identifier& identifier)
diff --git a/Source/JavaScriptCore/runtime/JSCell.h b/Source/JavaScriptCore/runtime/JSCell.h
index 78d2d0801..2ef359b76 100644
--- a/Source/JavaScriptCore/runtime/JSCell.h
+++ b/Source/JavaScriptCore/runtime/JSCell.h
@@ -107,7 +107,7 @@ namespace JSC {
const ClassInfo* validatedClassInfo() const;
const MethodTable* methodTable() const;
static void put(JSCell*, ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
- static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue);
+ static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
static bool deleteProperty(JSCell*, ExecState*, const Identifier& propertyName);
static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName);
diff --git a/Source/JavaScriptCore/runtime/JSDateMath.cpp b/Source/JavaScriptCore/runtime/JSDateMath.cpp
index 863073338..882f86fa0 100644
--- a/Source/JavaScriptCore/runtime/JSDateMath.cpp
+++ b/Source/JavaScriptCore/runtime/JSDateMath.cpp
@@ -72,8 +72,6 @@
#include "config.h"
#include "JSDateMath.h"
-#include "Assertions.h"
-#include "ASCIICType.h"
#include "CurrentTime.h"
#include "JSObject.h"
#include "MathExtras.h"
@@ -86,6 +84,8 @@
#include <limits>
#include <stdint.h>
#include <time.h>
+#include <wtf/ASCIICType.h>
+#include <wtf/Assertions.h>
#include <wtf/text/StringBuilder.h>
#if HAVE(ERRNO_H)
diff --git a/Source/JavaScriptCore/runtime/JSFunction.cpp b/Source/JavaScriptCore/runtime/JSFunction.cpp
index 253128279..fa798f41a 100644
--- a/Source/JavaScriptCore/runtime/JSFunction.cpp
+++ b/Source/JavaScriptCore/runtime/JSFunction.cpp
@@ -181,7 +181,15 @@ JSValue JSFunction::callerGetter(ExecState* exec, JSValue slotBase, const Identi
{
JSFunction* thisObj = asFunction(slotBase);
ASSERT(!thisObj->isHostFunction());
- return exec->interpreter()->retrieveCallerFromVMCode(exec, thisObj);
+ JSValue caller = exec->interpreter()->retrieveCallerFromVMCode(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::s_info))
+ return caller;
+ JSFunction* function = asFunction(caller);
+ if (function->isHostFunction() || !function->jsExecutable()->isStrictMode())
+ return caller;
+ return throwTypeError(exec, "Function.caller used to retrieve strict caller");
}
JSValue JSFunction::lengthGetter(ExecState*, JSValue slotBase, const Identifier&)
@@ -329,21 +337,80 @@ void JSFunction::put(JSCell* cell, ExecState* exec, const Identifier& propertyNa
Base::put(thisObject, exec, propertyName, value, slot);
return;
}
- if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
+ if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length || propertyName == exec->propertyNames().caller) {
+ if (slot.isStrictMode())
+ throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
return;
+ }
Base::put(thisObject, exec, propertyName, value, slot);
}
bool JSFunction::deleteProperty(JSCell* cell, ExecState* exec, const Identifier& propertyName)
{
JSFunction* thisObject = jsCast<JSFunction*>(cell);
- if (thisObject->isHostFunction())
- return Base::deleteProperty(thisObject, exec, propertyName);
- if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
+ // For non-host functions, don't let these properties by deleted - except by DefineOwnProperty.
+ if (!thisObject->isHostFunction() && !exec->globalData().isInDefineOwnProperty()
+ && (propertyName == exec->propertyNames().arguments
+ || propertyName == exec->propertyNames().length
+ || propertyName == exec->propertyNames().prototype
+ || propertyName == exec->propertyNames().caller))
return false;
return Base::deleteProperty(thisObject, exec, propertyName);
}
+bool JSFunction::defineOwnProperty(JSObject* object, ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor, bool throwException)
+{
+ JSFunction* thisObject = jsCast<JSFunction*>(object);
+ if (thisObject->isHostFunction())
+ return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
+
+ if (propertyName == exec->propertyNames().prototype) {
+ // Make sure prototype has been reified, such that it can only be overwritten
+ // following the rules set out in ECMA-262 8.12.9.
+ PropertySlot slot;
+ thisObject->methodTable()->getOwnPropertySlot(thisObject, exec, propertyName, slot);
+ } else if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length || propertyName == exec->propertyNames().caller) {
+ if (!object->isExtensible()) {
+ if (throwException)
+ throwError(exec, createTypeError(exec, "Attempting to define property on object that is not extensible."));
+ return false;
+ }
+ if (descriptor.configurablePresent() && descriptor.configurable()) {
+ if (throwException)
+ throwError(exec, createTypeError(exec, "Attempting to configurable attribute of unconfigurable property."));
+ return false;
+ }
+ if (descriptor.enumerablePresent() && descriptor.enumerable()) {
+ if (throwException)
+ throwError(exec, createTypeError(exec, "Attempting to change enumerable attribute of unconfigurable property."));
+ return false;
+ }
+ if (descriptor.isAccessorDescriptor()) {
+ if (throwException)
+ throwError(exec, createTypeError(exec, "Attempting to change access mechanism for an unconfigurable property."));
+ return false;
+ }
+ if (descriptor.writablePresent() && descriptor.writable()) {
+ if (throwException)
+ throwError(exec, createTypeError(exec, "Attempting to change writable attribute of unconfigurable property."));
+ return false;
+ }
+ if (!descriptor.value())
+ return true;
+ if (propertyName == exec->propertyNames().arguments && sameValue(exec, descriptor.value(), exec->interpreter()->retrieveArgumentsFromVMCode(exec, thisObject)))
+ return true;
+ if (propertyName == exec->propertyNames().length && sameValue(exec, descriptor.value(), jsNumber(thisObject->jsExecutable()->parameterCount())))
+ return true;
+ if (propertyName == exec->propertyNames().caller && sameValue(exec, descriptor.value(), exec->interpreter()->retrieveCallerFromVMCode(exec, thisObject)))
+ return true;
+ if (throwException)
+ throwError(exec, createTypeError(exec, "Attempting to change value of a readonly property."));
+ return false;
+ }
+
+ return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
+}
+
// ECMA 13.2.2 [[Construct]]
ConstructType JSFunction::getConstructData(JSCell* cell, ConstructData& constructData)
{
diff --git a/Source/JavaScriptCore/runtime/JSFunction.h b/Source/JavaScriptCore/runtime/JSFunction.h
index 6e8557f59..288181060 100644
--- a/Source/JavaScriptCore/runtime/JSFunction.h
+++ b/Source/JavaScriptCore/runtime/JSFunction.h
@@ -133,6 +133,7 @@ namespace JSC {
static bool getOwnPropertySlot(JSCell*, ExecState*, const Identifier&, PropertySlot&);
static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode = ExcludeDontEnumProperties);
+ static bool defineOwnProperty(JSObject*, ExecState*, const Identifier& propertyName, PropertyDescriptor&, bool shouldThrow);
static void put(JSCell*, ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
diff --git a/Source/JavaScriptCore/runtime/JSGlobalData.cpp b/Source/JavaScriptCore/runtime/JSGlobalData.cpp
index 2bdc28ab7..f138e75fb 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalData.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalData.cpp
@@ -193,7 +193,7 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread
wtfThreadData().setCurrentIdentifierTable(existingEntryIdentifierTable);
-#if ENABLE(JIT) && ENABLE(CLASSIC_INTERPRETER)
+#if ENABLE(JIT) && (ENABLE(CLASSIC_INTERPRETER) || ENABLE(LLINT))
#if USE(CF)
CFStringRef canUseJITKey = CFStringCreateWithCString(0 , "JavaScriptCoreUseJIT", kCFStringEncodingMacRoman);
CFBooleanRef canUseJIT = (CFBooleanRef)CFPreferencesCopyAppValue(canUseJITKey, kCFPreferencesCurrentApplication);
@@ -213,13 +213,16 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread
#endif
#endif
#if ENABLE(JIT)
-#if ENABLE(CLASSIC_INTERPRETER)
+#if ENABLE(CLASSIC_INTERPRETER) || ENABLE(LLINT)
if (m_canUseJIT)
m_canUseJIT = executableAllocator.isValid();
+
+ if (!Options::useJIT)
+ m_canUseJIT = false;
#endif
jitStubs = adoptPtr(new JITThunks(this));
#endif
-
+
interpreter->initialize(&llintData, this->canUseJIT());
initializeHostCallReturnValue(); // This is needed to convince the linker not to drop host call return support.
diff --git a/Source/JavaScriptCore/runtime/JSGlobalData.h b/Source/JavaScriptCore/runtime/JSGlobalData.h
index 7e54c00db..acbcee816 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalData.h
+++ b/Source/JavaScriptCore/runtime/JSGlobalData.h
@@ -47,6 +47,7 @@
#include <wtf/Forward.h>
#include <wtf/HashMap.h>
#include <wtf/RefCounted.h>
+#include <wtf/SimpleStats.h>
#include <wtf/ThreadSpecific.h>
#include <wtf/WTFThreadData.h>
#if ENABLE(REGEXP_TRACING)
@@ -201,6 +202,7 @@ namespace JSC {
SmallStrings smallStrings;
NumericStrings numericStrings;
DateInstanceCache dateInstanceCache;
+ WTF::SimpleStats machineCodeBytesPerBytecodeWordForBaselineJIT;
Vector<CodeBlock*> codeBlocksBeingCompiled;
void startedCompiling(CodeBlock* codeBlock)
{
@@ -229,7 +231,7 @@ namespace JSC {
#if !ENABLE(JIT)
bool canUseJIT() { return false; } // interpreter only
-#elif !ENABLE(CLASSIC_INTERPRETER)
+#elif !ENABLE(CLASSIC_INTERPRETER) && !ENABLE(LLINT)
bool canUseJIT() { return true; } // jit only
#else
bool canUseJIT() { return m_canUseJIT; }
@@ -367,7 +369,7 @@ namespace JSC {
JSGlobalData(GlobalDataType, ThreadStackType, HeapSize);
static JSGlobalData*& sharedInstanceInternal();
void createNativeThunk();
-#if ENABLE(JIT) && ENABLE(CLASSIC_INTERPRETER)
+#if ENABLE(JIT) && (ENABLE(CLASSIC_INTERPRETER) || ENABLE(LLINT))
bool m_canUseJIT;
#endif
#if ENABLE(GC_VALIDATION)
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp b/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
index db8ee1d85..75789e602 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
@@ -35,7 +35,7 @@
#include "Nodes.h"
#include "Parser.h"
#include "UStringBuilder.h"
-#include "dtoa.h"
+#include <wtf/dtoa.h>
#include <stdio.h>
#include <stdlib.h>
#include <wtf/ASCIICType.h>
diff --git a/Source/JavaScriptCore/runtime/JSNotAnObject.cpp b/Source/JavaScriptCore/runtime/JSNotAnObject.cpp
index 682400292..337e3a70c 100644
--- a/Source/JavaScriptCore/runtime/JSNotAnObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSNotAnObject.cpp
@@ -70,7 +70,7 @@ void JSNotAnObject::put(JSCell*, ExecState* exec, const Identifier& , JSValue, P
ASSERT_UNUSED(exec, exec->hadException());
}
-void JSNotAnObject::putByIndex(JSCell*, ExecState* exec, unsigned, JSValue)
+void JSNotAnObject::putByIndex(JSCell*, ExecState* exec, unsigned, JSValue, bool)
{
ASSERT_UNUSED(exec, exec->hadException());
}
diff --git a/Source/JavaScriptCore/runtime/JSNotAnObject.h b/Source/JavaScriptCore/runtime/JSNotAnObject.h
index 51ba456e1..5f80688b0 100644
--- a/Source/JavaScriptCore/runtime/JSNotAnObject.h
+++ b/Source/JavaScriptCore/runtime/JSNotAnObject.h
@@ -73,7 +73,7 @@ namespace JSC {
static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
static void put(JSCell*, ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
- static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue);
+ static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
static bool deleteProperty(JSCell*, ExecState*, const Identifier& propertyName);
static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName);
diff --git a/Source/JavaScriptCore/runtime/JSONObject.cpp b/Source/JavaScriptCore/runtime/JSONObject.cpp
index 83b118429..436e78353 100644
--- a/Source/JavaScriptCore/runtime/JSONObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSONObject.cpp
@@ -704,12 +704,8 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered)
JSValue filteredValue = callReviver(array, jsString(m_exec, UString::number(indexStack.last())), outValue);
if (filteredValue.isUndefined())
array->methodTable()->deletePropertyByIndex(array, m_exec, indexStack.last());
- else {
- if (isJSArray(array) && array->canSetIndex(indexStack.last()))
- array->setIndex(m_exec->globalData(), indexStack.last(), filteredValue);
- else
- array->methodTable()->putByIndex(array, m_exec, indexStack.last(), filteredValue);
- }
+ else
+ array->putDirectIndex(m_exec, indexStack.last(), filteredValue, false);
if (m_exec->hadException())
return jsNull();
indexStack.last()++;
diff --git a/Source/JavaScriptCore/runtime/JSObject.cpp b/Source/JavaScriptCore/runtime/JSObject.cpp
index acc4a181e..1bdb90ff6 100644
--- a/Source/JavaScriptCore/runtime/JSObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSObject.cpp
@@ -119,11 +119,6 @@ bool JSObject::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigned
return thisObject->methodTable()->getOwnPropertySlot(thisObject, exec, Identifier::from(exec, propertyName), slot);
}
-static void throwSetterError(ExecState* exec)
-{
- throwError(exec, createTypeError(exec, "setting a property that has only a getter"));
-}
-
// ECMA 8.6.2.2
void JSObject::put(JSCell* cell, ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
{
@@ -161,7 +156,7 @@ void JSObject::put(JSCell* cell, ExecState* exec, const Identifier& propertyName
JSObject* setterFunc = asGetterSetter(gs)->setter();
if (!setterFunc) {
if (slot.isStrictMode())
- throwSetterError(exec);
+ throwError(exec, createTypeError(exec, "setting a property that has only a getter"));
return;
}
@@ -190,9 +185,9 @@ void JSObject::put(JSCell* cell, ExecState* exec, const Identifier& propertyName
return;
}
-void JSObject::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue value)
+void JSObject::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue value, bool shouldThrow)
{
- PutPropertySlot slot;
+ PutPropertySlot slot(shouldThrow);
JSObject* thisObject = jsCast<JSObject*>(cell);
thisObject->methodTable()->put(thisObject, exec, Identifier::from(exec, propertyName), value, slot);
}
@@ -707,7 +702,7 @@ bool JSObject::defineOwnProperty(JSObject* object, ExecState* exec, const Identi
if (descriptor.isGenericDescriptor()) {
if (!current.attributesEqual(descriptor)) {
object->methodTable()->deleteProperty(object, exec, propertyName);
- return putDescriptor(exec, object, propertyName, descriptor, current.attributesWithOverride(descriptor), current);
+ return putDescriptor(exec, object, propertyName, descriptor, descriptor.attributesOverridingCurrent(current), current);
}
return true;
}
@@ -720,7 +715,7 @@ bool JSObject::defineOwnProperty(JSObject* object, ExecState* exec, const Identi
return false;
}
object->methodTable()->deleteProperty(object, exec, propertyName);
- return putDescriptor(exec, object, propertyName, descriptor, current.attributesWithOverride(descriptor), current);
+ return putDescriptor(exec, object, propertyName, descriptor, descriptor.attributesOverridingCurrent(current), current);
}
// Changing the value and attributes of an existing property
@@ -742,7 +737,7 @@ bool JSObject::defineOwnProperty(JSObject* object, ExecState* exec, const Identi
if (current.attributesEqual(descriptor) && !descriptor.value())
return true;
object->methodTable()->deleteProperty(object, exec, propertyName);
- return putDescriptor(exec, object, propertyName, descriptor, current.attributesWithOverride(descriptor), current);
+ return putDescriptor(exec, object, propertyName, descriptor, descriptor.attributesOverridingCurrent(current), current);
}
// Changing the accessor functions of an existing accessor property
diff --git a/Source/JavaScriptCore/runtime/JSObject.h b/Source/JavaScriptCore/runtime/JSObject.h
index c117cffaf..3f3d281cf 100644
--- a/Source/JavaScriptCore/runtime/JSObject.h
+++ b/Source/JavaScriptCore/runtime/JSObject.h
@@ -109,7 +109,7 @@ namespace JSC {
bool allowsAccessFrom(ExecState*);
JS_EXPORT_PRIVATE static void put(JSCell*, ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
- JS_EXPORT_PRIVATE static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue);
+ JS_EXPORT_PRIVATE static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
// putDirect is effectively an unchecked vesion of 'defineOwnProperty':
// - the prototype chain is not consulted
@@ -834,21 +834,20 @@ inline JSValue JSValue::get(ExecState* exec, unsigned propertyName, PropertySlot
inline void JSValue::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
{
if (UNLIKELY(!isCell())) {
- JSObject* thisObject = synthesizeObject(exec);
- thisObject->methodTable()->put(thisObject, exec, propertyName, value, slot);
+ putToPrimitive(exec, propertyName, value, slot);
return;
}
asCell()->methodTable()->put(asCell(), exec, propertyName, value, slot);
}
-inline void JSValue::put(ExecState* exec, unsigned propertyName, JSValue value)
+inline void JSValue::putByIndex(ExecState* exec, unsigned propertyName, JSValue value, bool shouldThrow)
{
if (UNLIKELY(!isCell())) {
- JSObject* thisObject = synthesizeObject(exec);
- thisObject->methodTable()->putByIndex(thisObject, exec, propertyName, value);
+ PutPropertySlot slot(shouldThrow);
+ putToPrimitive(exec, Identifier::from(exec, propertyName), value, slot);
return;
}
- asCell()->methodTable()->putByIndex(asCell(), exec, propertyName, value);
+ asCell()->methodTable()->putByIndex(asCell(), exec, propertyName, value, shouldThrow);
}
// --- JSValue inlines ----------------------------
diff --git a/Source/JavaScriptCore/runtime/JSString.cpp b/Source/JavaScriptCore/runtime/JSString.cpp
index cfa7d03b4..e84ce3620 100644
--- a/Source/JavaScriptCore/runtime/JSString.cpp
+++ b/Source/JavaScriptCore/runtime/JSString.cpp
@@ -65,9 +65,10 @@ void JSString::resolveRope(ExecState* exec) const
if (is8Bit()) {
LChar* buffer;
- if (RefPtr<StringImpl> newImpl = StringImpl::tryCreateUninitialized(m_length, buffer))
+ if (RefPtr<StringImpl> newImpl = StringImpl::tryCreateUninitialized(m_length, buffer)) {
+ Heap::heap(this)->reportExtraMemoryCost(newImpl->cost());
m_value = newImpl.release();
- else {
+ } else {
outOfMemory(exec);
return;
}
@@ -92,9 +93,10 @@ void JSString::resolveRope(ExecState* exec) const
}
UChar* buffer;
- if (RefPtr<StringImpl> newImpl = StringImpl::tryCreateUninitialized(m_length, buffer))
+ if (RefPtr<StringImpl> newImpl = StringImpl::tryCreateUninitialized(m_length, buffer)) {
+ Heap::heap(this)->reportExtraMemoryCost(newImpl->cost());
m_value = newImpl.release();
- else {
+ } else {
outOfMemory(exec);
return;
}
diff --git a/Source/JavaScriptCore/runtime/JSStringBuilder.h b/Source/JavaScriptCore/runtime/JSStringBuilder.h
index b7e7e781e..1a2b812f0 100644
--- a/Source/JavaScriptCore/runtime/JSStringBuilder.h
+++ b/Source/JavaScriptCore/runtime/JSStringBuilder.h
@@ -29,7 +29,7 @@
#include "ExceptionHelpers.h"
#include "JSString.h"
#include "UStringConcatenate.h"
-#include "Vector.h"
+#include <wtf/Vector.h>
namespace JSC {
diff --git a/Source/JavaScriptCore/runtime/JSValue.cpp b/Source/JavaScriptCore/runtime/JSValue.cpp
index e3843f02b..36697c60c 100644
--- a/Source/JavaScriptCore/runtime/JSValue.cpp
+++ b/Source/JavaScriptCore/runtime/JSValue.cpp
@@ -27,6 +27,7 @@
#include "BooleanPrototype.h"
#include "Error.h"
#include "ExceptionHelpers.h"
+#include "GetterSetter.h"
#include "JSGlobalObject.h"
#include "JSFunction.h"
#include "JSNotAnObject.h"
@@ -90,30 +91,85 @@ JSObject* JSValue::toThisObjectSlowCase(ExecState* exec) const
return exec->globalThisValue();
}
-JSObject* JSValue::synthesizeObject(ExecState* exec) const
+JSObject* JSValue::synthesizePrototype(ExecState* exec) const
{
- ASSERT(!isCell());
+ if (isCell()) {
+ ASSERT(isString());
+ return exec->lexicalGlobalObject()->stringPrototype();
+ }
+
if (isNumber())
- return constructNumber(exec, exec->lexicalGlobalObject(), asValue());
+ return exec->lexicalGlobalObject()->numberPrototype();
if (isBoolean())
- return constructBooleanFromImmediateBoolean(exec, exec->lexicalGlobalObject(), asValue());
+ return exec->lexicalGlobalObject()->booleanPrototype();
ASSERT(isUndefinedOrNull());
throwError(exec, createNotAnObjectError(exec, *this));
return JSNotAnObject::create(exec);
}
-JSObject* JSValue::synthesizePrototype(ExecState* exec) const
+// ECMA 8.7.2
+void JSValue::putToPrimitive(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
{
- ASSERT(!isCell());
- if (isNumber())
- return exec->lexicalGlobalObject()->numberPrototype();
- if (isBoolean())
- return exec->lexicalGlobalObject()->booleanPrototype();
+ JSGlobalData& globalData = exec->globalData();
- ASSERT(isUndefinedOrNull());
- throwError(exec, createNotAnObjectError(exec, *this));
- return JSNotAnObject::create(exec);
+ // Check if there are any setters or getters in the prototype chain
+ JSObject* obj = synthesizePrototype(exec);
+ JSValue prototype;
+ if (propertyName != exec->propertyNames().underscoreProto) {
+ for (; !obj->structure()->hasReadOnlyOrGetterSetterPropertiesExcludingProto(); obj = asObject(prototype)) {
+ prototype = obj->prototype();
+ if (prototype.isNull()) {
+ if (slot.isStrictMode())
+ throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
+ return;
+ }
+ }
+ }
+
+ for (; ; obj = asObject(prototype)) {
+ unsigned attributes;
+ JSCell* specificValue;
+ size_t offset = obj->structure()->get(globalData, propertyName, attributes, specificValue);
+ if (offset != WTF::notFound) {
+ if (attributes & ReadOnly) {
+ if (slot.isStrictMode())
+ throwError(exec, createTypeError(exec, StrictModeReadonlyPropertyWriteError));
+ return;
+ }
+
+ JSValue gs = obj->getDirectOffset(offset);
+ if (gs.isGetterSetter()) {
+ JSObject* setterFunc = asGetterSetter(gs)->setter();
+ if (!setterFunc) {
+ if (slot.isStrictMode())
+ throwError(exec, createTypeError(exec, "setting a property that has only a getter"));
+ return;
+ }
+
+ CallData callData;
+ CallType callType = setterFunc->methodTable()->getCallData(setterFunc, callData);
+ MarkedArgumentBuffer args;
+ args.append(value);
+
+ // If this is WebCore's global object then we need to substitute the shell.
+ call(exec, setterFunc, callType, callData, *this, args);
+ return;
+ }
+
+ // If there's an existing property on the object or one of its
+ // prototypes it should be replaced, so break here.
+ break;
+ }
+
+ prototype = obj->prototype();
+ if (prototype.isNull())
+ break;
+ }
+
+ if (slot.isStrictMode())
+ throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
+ return;
}
char* JSValue::description()
diff --git a/Source/JavaScriptCore/runtime/JSValue.h b/Source/JavaScriptCore/runtime/JSValue.h
index 9f797e05d..a6f359360 100644
--- a/Source/JavaScriptCore/runtime/JSValue.h
+++ b/Source/JavaScriptCore/runtime/JSValue.h
@@ -221,7 +221,8 @@ namespace JSC {
JSValue get(ExecState*, unsigned propertyName) const;
JSValue get(ExecState*, unsigned propertyName, PropertySlot&) const;
void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
- void put(ExecState*, unsigned propertyName, JSValue);
+ void putToPrimitive(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
+ void putByIndex(ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
JSObject* toThisObject(ExecState*) const;
@@ -252,8 +253,6 @@ namespace JSC {
JS_EXPORT_PRIVATE JSObject* toObjectSlowCase(ExecState*, JSGlobalObject*) const;
JS_EXPORT_PRIVATE JSObject* toThisObjectSlowCase(ExecState*) const;
- JSObject* synthesizeObject(ExecState*) const;
-
#if USE(JSVALUE32_64)
/*
* On 32-bit platforms USE(JSVALUE32_64) should be defined, and we use a NaN-encoded
diff --git a/Source/JavaScriptCore/runtime/JSVariableObject.h b/Source/JavaScriptCore/runtime/JSVariableObject.h
index 8d058f1fc..bcfe4ab89 100644
--- a/Source/JavaScriptCore/runtime/JSVariableObject.h
+++ b/Source/JavaScriptCore/runtime/JSVariableObject.h
@@ -32,7 +32,7 @@
#include "JSObject.h"
#include "Register.h"
#include "SymbolTable.h"
-#include "UnusedParam.h"
+#include <wtf/UnusedParam.h>
#include <wtf/OwnArrayPtr.h>
#include <wtf/UnusedParam.h>
diff --git a/Source/JavaScriptCore/runtime/NumberPrototype.cpp b/Source/JavaScriptCore/runtime/NumberPrototype.cpp
index fb90bcd17..8f8c3c00f 100644
--- a/Source/JavaScriptCore/runtime/NumberPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/NumberPrototype.cpp
@@ -29,7 +29,7 @@
#include "JSString.h"
#include "Operations.h"
#include "Uint16WithFraction.h"
-#include "dtoa.h"
+#include <wtf/dtoa.h>
#include <wtf/Assertions.h>
#include <wtf/MathExtras.h>
#include <wtf/Vector.h>
diff --git a/Source/JavaScriptCore/runtime/Options.cpp b/Source/JavaScriptCore/runtime/Options.cpp
index 5500508cf..c4bf39db4 100644
--- a/Source/JavaScriptCore/runtime/Options.cpp
+++ b/Source/JavaScriptCore/runtime/Options.cpp
@@ -45,6 +45,8 @@
namespace JSC { namespace Options {
+bool useJIT;
+
unsigned maximumOptimizationCandidateInstructionCount;
unsigned maximumFunctionForCallInlineCandidateInstructionCount;
@@ -52,15 +54,12 @@ unsigned maximumFunctionForConstructInlineCandidateInstructionCount;
unsigned maximumInliningDepth;
-int32_t executionCounterValueForJITAfterWarmUp;
-int32_t executionCounterValueForDontJITAnytimeSoon;
-int32_t executionCounterValueForJITSoon;
+int32_t thresholdForJITAfterWarmUp;
+int32_t thresholdForJITSoon;
-int32_t executionCounterValueForOptimizeAfterWarmUp;
-int32_t executionCounterValueForOptimizeAfterLongWarmUp;
-int32_t executionCounterValueForDontOptimizeAnytimeSoon;
-int32_t executionCounterValueForOptimizeSoon;
-int32_t executionCounterValueForOptimizeNextInvocation;
+int32_t thresholdForOptimizeAfterWarmUp;
+int32_t thresholdForOptimizeAfterLongWarmUp;
+int32_t thresholdForOptimizeSoon;
int32_t executionCounterIncrementForLoop;
int32_t executionCounterIncrementForReturn;
@@ -96,6 +95,19 @@ unsigned numberOfGCMarkers;
unsigned opaqueRootMergeThreshold;
#if ENABLE(RUN_TIME_HEURISTICS)
+static bool parse(const char* string, bool& value)
+{
+ if (!strcasecmp(string, "true") || !strcasecmp(string, "yes") || !strcmp(string, "1")) {
+ value = true;
+ return true;
+ }
+ if (!strcasecmp(string, "false") || !strcasecmp(string, "no") || !strcmp(string, "0")) {
+ value = false;
+ return true;
+ }
+ return false;
+}
+
static bool parse(const char* string, int32_t& value)
{
return sscanf(string, "%d", &value) == 1;
@@ -134,22 +146,21 @@ void setHeuristic(T& variable, const char* name, U value)
void initializeOptions()
{
- SET(maximumOptimizationCandidateInstructionCount, 1100);
+ SET(useJIT, true);
+
+ SET(maximumOptimizationCandidateInstructionCount, 10000);
SET(maximumFunctionForCallInlineCandidateInstructionCount, 180);
SET(maximumFunctionForConstructInlineCandidateInstructionCount, 100);
SET(maximumInliningDepth, 5);
- SET(executionCounterValueForJITAfterWarmUp, -100);
- SET(executionCounterValueForDontJITAnytimeSoon, std::numeric_limits<int32_t>::min());
- SET(executionCounterValueForJITSoon, -100);
+ SET(thresholdForJITAfterWarmUp, 100);
+ SET(thresholdForJITSoon, 100);
- SET(executionCounterValueForOptimizeAfterWarmUp, -1000);
- SET(executionCounterValueForOptimizeAfterLongWarmUp, -5000);
- SET(executionCounterValueForDontOptimizeAnytimeSoon, std::numeric_limits<int32_t>::min());
- SET(executionCounterValueForOptimizeSoon, -1000);
- SET(executionCounterValueForOptimizeNextInvocation, 0);
+ SET(thresholdForOptimizeAfterWarmUp, 1000);
+ SET(thresholdForOptimizeAfterLongWarmUp, 5000);
+ SET(thresholdForOptimizeSoon, 1000);
SET(executionCounterIncrementForLoop, 1);
SET(executionCounterIncrementForReturn, 15);
@@ -193,15 +204,11 @@ void initializeOptions()
if (cpusToUse < 1)
cpusToUse = 1;
- cpusToUse = 1;
-
SET(numberOfGCMarkers, cpusToUse);
- ASSERT(executionCounterValueForDontOptimizeAnytimeSoon <= executionCounterValueForOptimizeAfterLongWarmUp);
- ASSERT(executionCounterValueForOptimizeAfterLongWarmUp <= executionCounterValueForOptimizeAfterWarmUp);
- ASSERT(executionCounterValueForOptimizeAfterWarmUp <= executionCounterValueForOptimizeSoon);
- ASSERT(executionCounterValueForOptimizeAfterWarmUp < 0);
- ASSERT(executionCounterValueForOptimizeSoon <= executionCounterValueForOptimizeNextInvocation);
+ ASSERT(thresholdForOptimizeAfterLongWarmUp >= thresholdForOptimizeAfterWarmUp);
+ ASSERT(thresholdForOptimizeAfterWarmUp >= thresholdForOptimizeSoon);
+ ASSERT(thresholdForOptimizeAfterWarmUp >= 0);
// 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
@@ -209,11 +216,11 @@ void initializeOptions()
// up being 18, so this loop is not so terrible; it probably takes up ~100 cycles
// total on a 32-bit processor.
reoptimizationRetryCounterMax = 0;
- while ((static_cast<int64_t>(executionCounterValueForOptimizeAfterLongWarmUp) << (reoptimizationRetryCounterMax + 1)) >= static_cast<int64_t>(std::numeric_limits<int32_t>::min()))
+ while ((static_cast<int64_t>(thresholdForOptimizeAfterLongWarmUp) << (reoptimizationRetryCounterMax + 1)) <= static_cast<int64_t>(std::numeric_limits<int32_t>::max()))
reoptimizationRetryCounterMax++;
- ASSERT((static_cast<int64_t>(executionCounterValueForOptimizeAfterLongWarmUp) << reoptimizationRetryCounterMax) < 0);
- ASSERT((static_cast<int64_t>(executionCounterValueForOptimizeAfterLongWarmUp) << reoptimizationRetryCounterMax) >= static_cast<int64_t>(std::numeric_limits<int32_t>::min()));
+ ASSERT((static_cast<int64_t>(thresholdForOptimizeAfterLongWarmUp) << reoptimizationRetryCounterMax) > 0);
+ ASSERT((static_cast<int64_t>(thresholdForOptimizeAfterLongWarmUp) << reoptimizationRetryCounterMax) <= static_cast<int64_t>(std::numeric_limits<int32_t>::max()));
}
} } // namespace JSC::Options
diff --git a/Source/JavaScriptCore/runtime/Options.h b/Source/JavaScriptCore/runtime/Options.h
index b9e68f90c..fae6a7376 100644
--- a/Source/JavaScriptCore/runtime/Options.h
+++ b/Source/JavaScriptCore/runtime/Options.h
@@ -30,6 +30,8 @@
namespace JSC { namespace Options {
+extern bool useJIT;
+
extern unsigned maximumOptimizationCandidateInstructionCount;
extern unsigned maximumFunctionForCallInlineCandidateInstructionCount;
@@ -37,15 +39,13 @@ extern unsigned maximumFunctionForConstructInlineCandidateInstructionCount;
extern unsigned maximumInliningDepth; // Depth of inline stack, so 1 = no inlining, 2 = one level, etc.
-extern int32_t executionCounterValueForJITAfterWarmUp;
-extern int32_t executionCounterValueForDontJITAnytimeSoon;
-extern int32_t executionCounterValueForJITSoon;
+extern int32_t thresholdForJITAfterWarmUp;
+extern int32_t thresholdForJITSoon;
-extern int32_t executionCounterValueForOptimizeAfterWarmUp;
-extern int32_t executionCounterValueForOptimizeAfterLongWarmUp;
-extern int32_t executionCounterValueForDontOptimizeAnytimeSoon;
-extern int32_t executionCounterValueForOptimizeSoon;
-extern int32_t executionCounterValueForOptimizeNextInvocation;
+extern int32_t thresholdForOptimizeAfterWarmUp;
+extern int32_t thresholdForOptimizeAfterLongWarmUp;
+extern int32_t thresholdForOptimizeSoon;
+extern int32_t thresholdForOptimizeNextInvocation;
extern int32_t executionCounterIncrementForLoop;
extern int32_t executionCounterIncrementForReturn;
diff --git a/Source/JavaScriptCore/runtime/PropertyDescriptor.cpp b/Source/JavaScriptCore/runtime/PropertyDescriptor.cpp
index 0cb629584..236a8e5ae 100644
--- a/Source/JavaScriptCore/runtime/PropertyDescriptor.cpp
+++ b/Source/JavaScriptCore/runtime/PropertyDescriptor.cpp
@@ -206,22 +206,6 @@ bool PropertyDescriptor::attributesEqual(const PropertyDescriptor& other) const
return true;
}
-unsigned PropertyDescriptor::attributesWithOverride(const PropertyDescriptor& other) const
-{
- unsigned mismatch = other.m_attributes ^ m_attributes;
- unsigned sharedSeen = other.m_seenAttributes & m_seenAttributes;
- unsigned newAttributes = m_attributes & defaultAttributes;
- if (sharedSeen & WritablePresent && mismatch & ReadOnly)
- newAttributes ^= ReadOnly;
- if (sharedSeen & ConfigurablePresent && mismatch & DontDelete)
- newAttributes ^= DontDelete;
- if (sharedSeen & EnumerablePresent && mismatch & DontEnum)
- newAttributes ^= DontEnum;
- if (isAccessorDescriptor() && other.isDataDescriptor())
- newAttributes |= ReadOnly;
- return newAttributes;
-}
-
unsigned PropertyDescriptor::attributesOverridingCurrent(const PropertyDescriptor& current) const
{
unsigned currentAttributes = current.m_attributes;
diff --git a/Source/JavaScriptCore/runtime/PropertyDescriptor.h b/Source/JavaScriptCore/runtime/PropertyDescriptor.h
index 98af02e66..2c3878f57 100644
--- a/Source/JavaScriptCore/runtime/PropertyDescriptor.h
+++ b/Source/JavaScriptCore/runtime/PropertyDescriptor.h
@@ -70,7 +70,6 @@ namespace JSC {
bool getterPresent() const { return m_getter; }
bool equalTo(ExecState* exec, const PropertyDescriptor& other) const;
bool attributesEqual(const PropertyDescriptor& other) const;
- unsigned attributesWithOverride(const PropertyDescriptor& other) const;
unsigned attributesOverridingCurrent(const PropertyDescriptor& current) const;
private:
diff --git a/Source/JavaScriptCore/runtime/PropertySlot.cpp b/Source/JavaScriptCore/runtime/PropertySlot.cpp
index edabd7a6e..8ac874115 100644
--- a/Source/JavaScriptCore/runtime/PropertySlot.cpp
+++ b/Source/JavaScriptCore/runtime/PropertySlot.cpp
@@ -34,11 +34,7 @@ JSValue PropertySlot::functionGetter(ExecState* exec) const
CallData callData;
CallType callType = m_data.getterFunc->methodTable()->getCallData(m_data.getterFunc, callData);
-
- // Only objects can have accessor properties.
- // If the base is WebCore's global object then we need to substitute the shell.
- ASSERT(m_slotBase.isObject());
- return call(exec, m_data.getterFunc, callType, callData, m_thisValue.toThisObject(exec), exec->emptyList());
+ return call(exec, m_data.getterFunc, callType, callData, m_thisValue.isObject() ? m_thisValue.toThisObject(exec) : m_thisValue, exec->emptyList());
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/RegExp.cpp b/Source/JavaScriptCore/runtime/RegExp.cpp
index 2b7feb4b5..1a3362b2d 100644
--- a/Source/JavaScriptCore/runtime/RegExp.cpp
+++ b/Source/JavaScriptCore/runtime/RegExp.cpp
@@ -363,7 +363,33 @@ int RegExp::match(JSGlobalData& globalData, const UString& s, unsigned startOffs
#endif
} else
#endif
- result = Yarr::interpret(m_representation->m_regExpBytecode.get(), s, startOffset, s.length(), offsetVector);
+ result = Yarr::interpret(m_representation->m_regExpBytecode.get(), s, startOffset, s.length(), reinterpret_cast<unsigned*>(offsetVector));
+
+ // FIXME: The YARR engine should handle unsigned or size_t length matches.
+ // The YARR Interpreter is "unsigned" clean, while the YARR JIT hasn't been addressed.
+ // The offset vector handling needs to change as well.
+ // Right now we convert a match where the offsets overflowed into match failure.
+ // There are two places in WebCore that call the interpreter directly that need to
+ // have their offsets changed to int as well. They are platform/text/RegularExpression.cpp
+ // and inspector/ContentSearchUtils.cpp.
+ if (s.length() > INT_MAX) {
+ bool overflowed = false;
+
+ if (result < -1)
+ overflowed = true;
+
+ for (unsigned i = 0; i <= m_numSubpatterns; i++) {
+ if ((offsetVector[i*2] < -1) || ((offsetVector[i*2] >= 0) && (offsetVector[i*2+1] < -1))) {
+ overflowed = true;
+ offsetVector[i*2] = -1;
+ offsetVector[i*2+1] = -1;
+ }
+ }
+
+ if (overflowed)
+ result = -1;
+ }
+
ASSERT(result >= -1);
#if REGEXP_FUNC_TEST_DATA_GEN
diff --git a/Source/JavaScriptCore/runtime/RegExpConstructor.cpp b/Source/JavaScriptCore/runtime/RegExpConstructor.cpp
index 53e880e70..90082f07e 100644
--- a/Source/JavaScriptCore/runtime/RegExpConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpConstructor.cpp
@@ -153,9 +153,9 @@ void RegExpMatchesArray::fillArrayInstance(ExecState* exec)
for (unsigned i = 0; i <= lastNumSubpatterns; ++i) {
int start = m_regExpResult.ovector[2 * i];
if (start >= 0)
- JSArray::putByIndex(this, exec, i, jsSubstring(exec, m_regExpResult.input, start, m_regExpResult.ovector[2 * i + 1] - start));
+ putDirectIndex(exec, i, jsSubstring(exec, m_regExpResult.input, start, m_regExpResult.ovector[2 * i + 1] - start), false);
else
- JSArray::putByIndex(this, exec, i, jsUndefined());
+ putDirectIndex(exec, i, jsUndefined(), false);
}
PutPropertySlot slot;
diff --git a/Source/JavaScriptCore/runtime/RegExpMatchesArray.h b/Source/JavaScriptCore/runtime/RegExpMatchesArray.h
index c34920d8d..a3c4497fc 100644
--- a/Source/JavaScriptCore/runtime/RegExpMatchesArray.h
+++ b/Source/JavaScriptCore/runtime/RegExpMatchesArray.h
@@ -82,12 +82,12 @@ namespace JSC {
JSArray::put(thisObject, exec, propertyName, v, slot);
}
- static void putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue v)
+ static void putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue v, bool shouldThrow)
{
RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(cell);
if (!thisObject->m_didFillArrayInstance)
thisObject->fillArrayInstance(exec);
- JSArray::putByIndex(thisObject, exec, propertyName, v);
+ JSArray::putByIndex(thisObject, exec, propertyName, v, shouldThrow);
}
static bool deleteProperty(JSCell* cell, ExecState* exec, const Identifier& propertyName)
diff --git a/Source/JavaScriptCore/runtime/RegExpObject.cpp b/Source/JavaScriptCore/runtime/RegExpObject.cpp
index 4c192ff90..a81799c46 100644
--- a/Source/JavaScriptCore/runtime/RegExpObject.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpObject.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- * Copyright (C) 2003, 2007, 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2003, 2007, 2008, 2012 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
@@ -40,8 +40,6 @@ static JSValue regExpObjectGlobal(ExecState*, JSValue, const Identifier&);
static JSValue regExpObjectIgnoreCase(ExecState*, JSValue, const Identifier&);
static JSValue regExpObjectMultiline(ExecState*, JSValue, const Identifier&);
static JSValue regExpObjectSource(ExecState*, JSValue, const Identifier&);
-static JSValue regExpObjectLastIndex(ExecState*, JSValue, const Identifier&);
-static void setRegExpObjectLastIndex(ExecState*, JSObject*, JSValue);
} // namespace JSC
@@ -59,14 +57,15 @@ const ClassInfo RegExpObject::s_info = { "RegExp", &JSNonFinalObject::s_info, 0,
ignoreCase regExpObjectIgnoreCase DontDelete|ReadOnly|DontEnum
multiline regExpObjectMultiline DontDelete|ReadOnly|DontEnum
source regExpObjectSource DontDelete|ReadOnly|DontEnum
- lastIndex regExpObjectLastIndex DontDelete|DontEnum
@end
*/
RegExpObject::RegExpObject(JSGlobalObject* globalObject, Structure* structure, RegExp* regExp)
: JSNonFinalObject(globalObject->globalData(), structure)
- , d(adoptPtr(new RegExpObjectData(globalObject->globalData(), this, regExp)))
+ , m_regExp(globalObject->globalData(), this, regExp)
+ , m_lastIndexIsWritable(true)
{
+ m_lastIndex.setWithoutWriteBarrier(jsNumber(0));
}
void RegExpObject::finishCreation(JSGlobalObject* globalObject)
@@ -75,11 +74,6 @@ void RegExpObject::finishCreation(JSGlobalObject* globalObject)
ASSERT(inherits(&s_info));
}
-void RegExpObject::destroy(JSCell* cell)
-{
- jsCast<RegExpObject*>(cell)->RegExpObject::~RegExpObject();
-}
-
void RegExpObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
{
RegExpObject* thisObject = jsCast<RegExpObject*>(cell);
@@ -87,22 +81,87 @@ void RegExpObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
Base::visitChildren(thisObject, visitor);
- if (thisObject->d->regExp)
- visitor.append(&thisObject->d->regExp);
- if (UNLIKELY(!thisObject->d->lastIndex.get().isInt32()))
- visitor.append(&thisObject->d->lastIndex);
+ if (thisObject->m_regExp)
+ visitor.append(&thisObject->m_regExp);
+ if (UNLIKELY(!thisObject->m_lastIndex.get().isInt32()))
+ visitor.append(&thisObject->m_lastIndex);
}
bool RegExpObject::getOwnPropertySlot(JSCell* cell, ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
+ if (propertyName == exec->propertyNames().lastIndex) {
+ RegExpObject* regExp = asRegExpObject(cell);
+ slot.setValue(regExp, regExp->getLastIndex());
+ return true;
+ }
return getStaticValueSlot<RegExpObject, JSObject>(exec, ExecState::regExpTable(exec), jsCast<RegExpObject*>(cell), propertyName, slot);
}
bool RegExpObject::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
+ if (propertyName == exec->propertyNames().lastIndex) {
+ RegExpObject* regExp = asRegExpObject(object);
+ descriptor.setDescriptor(regExp->getLastIndex(), regExp->m_lastIndexIsWritable ? DontDelete | DontEnum : DontDelete | DontEnum | ReadOnly);
+ return true;
+ }
return getStaticValueDescriptor<RegExpObject, JSObject>(exec, ExecState::regExpTable(exec), jsCast<RegExpObject*>(object), propertyName, descriptor);
}
+bool RegExpObject::deleteProperty(JSCell* cell, ExecState* exec, const Identifier& propertyName)
+{
+ if (propertyName == exec->propertyNames().lastIndex)
+ return false;
+ return Base::deleteProperty(cell, exec, propertyName);
+}
+
+void RegExpObject::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
+{
+ if (mode == IncludeDontEnumProperties)
+ propertyNames.add(exec->propertyNames().lastIndex);
+ Base::getOwnPropertyNames(object, exec, propertyNames, mode);
+}
+
+void RegExpObject::getPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
+{
+ if (mode == IncludeDontEnumProperties)
+ propertyNames.add(exec->propertyNames().lastIndex);
+ Base::getPropertyNames(object, exec, propertyNames, mode);
+}
+
+static bool reject(ExecState* exec, bool throwException, const char* message)
+{
+ if (throwException)
+ throwTypeError(exec, message);
+ return false;
+}
+
+bool RegExpObject::defineOwnProperty(JSObject* object, ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor, bool shouldThrow)
+{
+ if (propertyName == exec->propertyNames().lastIndex) {
+ RegExpObject* regExp = asRegExpObject(object);
+ if (descriptor.configurablePresent() && descriptor.configurable())
+ return reject(exec, shouldThrow, "Attempting to change configurable attribute of unconfigurable property.");
+ if (descriptor.enumerablePresent() && descriptor.enumerable())
+ return reject(exec, shouldThrow, "Attempting to change enumerable attribute of unconfigurable property.");
+ if (descriptor.isAccessorDescriptor())
+ return reject(exec, shouldThrow, "Attempting to change access mechanism for an unconfigurable property.");
+ if (!regExp->m_lastIndexIsWritable) {
+ if (descriptor.writablePresent() && descriptor.writable())
+ return reject(exec, shouldThrow, "Attempting to change writable attribute of unconfigurable property.");
+ if (!sameValue(exec, regExp->getLastIndex(), descriptor.value()))
+ return reject(exec, shouldThrow, "Attempting to change value of a readonly property.");
+ return true;
+ }
+ if (descriptor.writablePresent() && !descriptor.writable())
+ regExp->m_lastIndexIsWritable = false;
+ if (descriptor.value())
+ regExp->setLastIndex(exec, descriptor.value(), false);
+ return true;
+ }
+
+ return Base::defineOwnProperty(object, exec, propertyName, descriptor, shouldThrow);
+}
+
JSValue regExpObjectGlobal(ExecState*, JSValue slotBase, const Identifier&)
{
return jsBoolean(asRegExpObject(slotBase)->regExp()->global());
@@ -127,6 +186,14 @@ JSValue regExpObjectSource(ExecState* exec, JSValue slotBase, const Identifier&)
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 jsString(exec, "(?:)");
+
// early return for strings that don't contain a forwards slash and LineTerminator
for (unsigned i = 0; i < length; ++i) {
UChar ch = characters[i];
@@ -200,21 +267,15 @@ JSValue regExpObjectSource(ExecState* exec, JSValue slotBase, const Identifier&)
return jsString(exec, result.toUString());
}
-JSValue regExpObjectLastIndex(ExecState*, JSValue slotBase, const Identifier&)
-{
- return asRegExpObject(slotBase)->getLastIndex();
-}
-
void RegExpObject::put(JSCell* cell, ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
{
+ if (propertyName == exec->propertyNames().lastIndex) {
+ asRegExpObject(cell)->setLastIndex(exec, value, slot.isStrictMode());
+ return;
+ }
lookupPut<RegExpObject, JSObject>(exec, propertyName, value, ExecState::regExpTable(exec), jsCast<RegExpObject*>(cell), slot);
}
-void setRegExpObjectLastIndex(ExecState* exec, JSObject* baseObject, JSValue value)
-{
- asRegExpObject(baseObject)->setLastIndex(exec->globalData(), value);
-}
-
JSValue RegExpObject::test(ExecState* exec)
{
return jsBoolean(match(exec));
@@ -236,7 +297,7 @@ bool RegExpObject::match(ExecState* exec)
if (!regExp()->global()) {
int position;
int length;
- regExpConstructor->performMatch(*globalData, d->regExp.get(), input, 0, position, length);
+ regExpConstructor->performMatch(*globalData, m_regExp.get(), input, 0, position, length);
return position >= 0;
}
@@ -245,13 +306,13 @@ bool RegExpObject::match(ExecState* exec)
if (LIKELY(jsLastIndex.isUInt32())) {
lastIndex = jsLastIndex.asUInt32();
if (lastIndex > input.length()) {
- setLastIndex(0);
+ setLastIndex(exec, 0);
return false;
}
} else {
double doubleLastIndex = jsLastIndex.toInteger(exec);
if (doubleLastIndex < 0 || doubleLastIndex > input.length()) {
- setLastIndex(0);
+ setLastIndex(exec, 0);
return false;
}
lastIndex = static_cast<unsigned>(doubleLastIndex);
@@ -259,13 +320,13 @@ bool RegExpObject::match(ExecState* exec)
int position;
int length = 0;
- regExpConstructor->performMatch(*globalData, d->regExp.get(), input, lastIndex, position, length);
+ regExpConstructor->performMatch(*globalData, m_regExp.get(), input, lastIndex, position, length);
if (position < 0) {
- setLastIndex(0);
+ setLastIndex(exec, 0);
return false;
}
- setLastIndex(position + length);
+ setLastIndex(exec, position + length);
return true;
}
diff --git a/Source/JavaScriptCore/runtime/RegExpObject.h b/Source/JavaScriptCore/runtime/RegExpObject.h
index 081a7f111..456cfa683 100644
--- a/Source/JavaScriptCore/runtime/RegExpObject.h
+++ b/Source/JavaScriptCore/runtime/RegExpObject.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- * Copyright (C) 2003, 2007, 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2003, 2007, 2008, 2012 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
@@ -44,20 +44,27 @@ namespace JSC {
return object;
}
- void setRegExp(JSGlobalData& globalData, RegExp* r) { d->regExp.set(globalData, this, r); }
- RegExp* regExp() const { return d->regExp.get(); }
+ void setRegExp(JSGlobalData& globalData, RegExp* r) { m_regExp.set(globalData, this, r); }
+ RegExp* regExp() const { return m_regExp.get(); }
- void setLastIndex(size_t lastIndex)
+ void setLastIndex(ExecState* exec, size_t lastIndex)
{
- d->lastIndex.setWithoutWriteBarrier(jsNumber(lastIndex));
+ m_lastIndex.setWithoutWriteBarrier(jsNumber(lastIndex));
+ if (LIKELY(m_lastIndexIsWritable))
+ m_lastIndex.setWithoutWriteBarrier(jsNumber(lastIndex));
+ else
+ throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
}
- void setLastIndex(JSGlobalData& globalData, JSValue lastIndex)
+ void setLastIndex(ExecState* exec, JSValue lastIndex, bool shouldThrow)
{
- d->lastIndex.set(globalData, this, lastIndex);
+ if (LIKELY(m_lastIndexIsWritable))
+ m_lastIndex.set(exec->globalData(), this, lastIndex);
+ else if (shouldThrow)
+ throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
}
JSValue getLastIndex() const
{
- return d->lastIndex.get();
+ return m_lastIndex.get();
}
JSValue test(ExecState*);
@@ -77,31 +84,22 @@ namespace JSC {
protected:
JS_EXPORT_PRIVATE RegExpObject(JSGlobalObject*, Structure*, RegExp*);
JS_EXPORT_PRIVATE void finishCreation(JSGlobalObject*);
- static void destroy(JSCell*);
static const unsigned StructureFlags = OverridesVisitChildren | OverridesGetOwnPropertySlot | Base::StructureFlags;
static void visitChildren(JSCell*, SlotVisitor&);
+ JS_EXPORT_PRIVATE static bool deleteProperty(JSCell*, ExecState*, const Identifier& propertyName);
+ JS_EXPORT_PRIVATE static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
+ JS_EXPORT_PRIVATE static void getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
+ JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, const Identifier& propertyName, PropertyDescriptor&, bool shouldThrow);
+
private:
bool match(ExecState*);
- struct RegExpObjectData {
- WTF_MAKE_FAST_ALLOCATED;
- public:
- RegExpObjectData(JSGlobalData& globalData, RegExpObject* owner, RegExp* regExp)
- : regExp(globalData, owner, regExp)
- {
- lastIndex.setWithoutWriteBarrier(jsNumber(0));
- }
-
- WriteBarrier<RegExp> regExp;
- WriteBarrier<Unknown> lastIndex;
- };
-#if COMPILER(MSVC)
- friend void WTF::deleteOwnedPtr<RegExpObjectData>(RegExpObjectData*);
-#endif
- OwnPtr<RegExpObjectData> d;
+ WriteBarrier<RegExp> m_regExp;
+ WriteBarrier<Unknown> m_lastIndex;
+ bool m_lastIndexIsWritable;
};
RegExpObject* asRegExpObject(JSValue);
diff --git a/Source/JavaScriptCore/runtime/RegExpPrototype.cpp b/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
index 9074e97c3..8e4b5a9d5 100644
--- a/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
@@ -129,7 +129,7 @@ EncodedJSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState* exec)
return throwVMError(exec, createSyntaxError(exec, regExp->errorMessage()));
asRegExpObject(thisValue)->setRegExp(exec->globalData(), regExp);
- asRegExpObject(thisValue)->setLastIndex(0);
+ asRegExpObject(thisValue)->setLastIndex(exec, 0);
return JSValue::encode(jsUndefined());
}
@@ -155,7 +155,7 @@ EncodedJSValue JSC_HOST_CALL regExpProtoFuncToString(ExecState* exec)
postfix[index] = 'm';
UString 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.length() ? source : UString("(?:)"), postfix));
+ return JSValue::encode(jsMakeNontrivialString(exec, "/", source, postfix));
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/StringObject.cpp b/Source/JavaScriptCore/runtime/StringObject.cpp
index 4a24698fb..d7e1c8a17 100644
--- a/Source/JavaScriptCore/runtime/StringObject.cpp
+++ b/Source/JavaScriptCore/runtime/StringObject.cpp
@@ -21,6 +21,7 @@
#include "config.h"
#include "StringObject.h"
+#include "Error.h"
#include "PropertyNameArray.h"
namespace JSC {
@@ -68,11 +69,56 @@ bool StringObject::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, c
void StringObject::put(JSCell* cell, ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
{
- if (propertyName == exec->propertyNames().length)
+ if (propertyName == exec->propertyNames().length) {
+ if (slot.isStrictMode())
+ throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
return;
+ }
JSObject::put(cell, exec, propertyName, value, slot);
}
+bool StringObject::defineOwnProperty(JSObject* object, ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor, bool throwException)
+{
+ StringObject* thisObject = jsCast<StringObject*>(object);
+
+ if (propertyName == exec->propertyNames().length) {
+ if (!object->isExtensible()) {
+ if (throwException)
+ throwError(exec, createTypeError(exec, "Attempting to define property on object that is not extensible."));
+ return false;
+ }
+ if (descriptor.configurablePresent() && descriptor.configurable()) {
+ if (throwException)
+ throwError(exec, createTypeError(exec, "Attempting to configurable attribute of unconfigurable property."));
+ return false;
+ }
+ if (descriptor.enumerablePresent() && descriptor.enumerable()) {
+ if (throwException)
+ throwError(exec, createTypeError(exec, "Attempting to change enumerable attribute of unconfigurable property."));
+ return false;
+ }
+ if (descriptor.isAccessorDescriptor()) {
+ if (throwException)
+ throwError(exec, createTypeError(exec, "Attempting to change access mechanism for an unconfigurable property."));
+ return false;
+ }
+ if (descriptor.writablePresent() && descriptor.writable()) {
+ if (throwException)
+ throwError(exec, createTypeError(exec, "Attempting to change writable attribute of unconfigurable property."));
+ return false;
+ }
+ if (!descriptor.value())
+ return true;
+ if (propertyName == exec->propertyNames().length && sameValue(exec, descriptor.value(), jsNumber(thisObject->internalValue()->length())))
+ return true;
+ if (throwException)
+ throwError(exec, createTypeError(exec, "Attempting to change value of a readonly property."));
+ return false;
+ }
+
+ return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
+}
+
bool StringObject::deleteProperty(JSCell* cell, ExecState* exec, const Identifier& propertyName)
{
StringObject* thisObject = jsCast<StringObject*>(cell);
diff --git a/Source/JavaScriptCore/runtime/StringObject.h b/Source/JavaScriptCore/runtime/StringObject.h
index 248c71601..bad5595c3 100644
--- a/Source/JavaScriptCore/runtime/StringObject.h
+++ b/Source/JavaScriptCore/runtime/StringObject.h
@@ -53,6 +53,7 @@ namespace JSC {
static bool deleteProperty(JSCell*, ExecState*, const Identifier& propertyName);
static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
+ static bool defineOwnProperty(JSObject*, ExecState*, const Identifier& propertyName, PropertyDescriptor&, bool shouldThrow);
static const JS_EXPORTDATA ClassInfo s_info;
diff --git a/Source/JavaScriptCore/runtime/StringPrototype.cpp b/Source/JavaScriptCore/runtime/StringPrototype.cpp
index 63c00e27e..708c1fb77 100644
--- a/Source/JavaScriptCore/runtime/StringPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/StringPrototype.cpp
@@ -455,11 +455,19 @@ static NEVER_INLINE EncodedJSValue replaceUsingRegExpSearch(ExecState* exec, JSS
unsigned sourceLen = source.length();
if (exec->hadException())
return JSValue::encode(JSValue());
- RegExp* regExp = asRegExpObject(searchValue)->regExp();
+ RegExpObject* regExpObject = asRegExpObject(searchValue);
+ RegExp* regExp = regExpObject->regExp();
bool global = regExp->global();
- if (global && callType == CallTypeNone && !replacementString.length())
- return removeUsingRegExpSearch(exec, string, source, regExp);
+ if (global) {
+ // ES5.1 15.5.4.10 step 8.a.
+ regExpObject->setLastIndex(exec, 0);
+ if (exec->hadException())
+ return JSValue::encode(JSValue());
+
+ if (callType == CallTypeNone && !replacementString.length())
+ return removeUsingRegExpSearch(exec, string, source, regExp);
+ }
RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
@@ -808,9 +816,17 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec)
JSValue a0 = exec->argument(0);
RegExp* reg;
- if (a0.inherits(&RegExpObject::s_info))
- reg = asRegExpObject(a0)->regExp();
- else {
+ bool global = false;
+ if (a0.inherits(&RegExpObject::s_info)) {
+ RegExpObject* regExpObject = asRegExpObject(a0);
+ reg = regExpObject->regExp();
+ if ((global = reg->global())) {
+ // ES5.1 15.5.4.10 step 8.a.
+ regExpObject->setLastIndex(exec, 0);
+ if (exec->hadException())
+ return JSValue::encode(JSValue());
+ }
+ } else {
/*
* ECMA 15.5.4.12 String.prototype.search (regexp)
* If regexp is not an object whose [[Class]] property is "RegExp", it is
@@ -825,7 +841,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec)
int pos;
int matchLength = 0;
regExpConstructor->performMatch(*globalData, reg, s, 0, pos, matchLength);
- if (!(reg->global())) {
+ if (!global) {
// case without 'g' flag is handled like RegExp.prototype.exec
if (pos < 0)
return JSValue::encode(jsNull());
@@ -948,7 +964,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec)
if (separatorValue.isUndefined()) {
// a. Call the [[DefineOwnProperty]] internal method of A with arguments "0",
// Property Descriptor {[[Value]]: S, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false.
- result->methodTable()->putByIndex(result, exec, 0, jsStringWithReuse(exec, thisValue, input));
+ result->putDirectIndex(exec, 0, jsStringWithReuse(exec, thisValue, input), false);
// b. Return A.
return JSValue::encode(result);
}
@@ -961,7 +977,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec)
// Property Descriptor {[[Value]]: S, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false.
// d. Return A.
if (reg->match(*globalData, input, 0) < 0)
- result->methodTable()->putByIndex(result, exec, 0, jsStringWithReuse(exec, thisValue, input));
+ result->putDirectIndex(exec, 0, jsStringWithReuse(exec, thisValue, input), false);
return JSValue::encode(result);
}
@@ -992,7 +1008,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->methodTable()->putByIndex(result, exec, resultLength, jsSubstring(exec, input, position, matchPosition - position));
+ result->putDirectIndex(exec, resultLength, jsSubstring(exec, input, position, matchPosition - position), false);
// 3. Increment lengthA by 1.
// 4. If lengthA == lim, return A.
if (++resultLength == limit)
@@ -1011,7 +1027,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->methodTable()->putByIndex(result, exec, resultLength, sub < 0 ? jsUndefined() : jsSubstring(exec, input, sub, ovector[i * 2 + 1] - sub));
+ result->putDirectIndex(exec, resultLength, sub < 0 ? jsUndefined() : jsSubstring(exec, input, sub, ovector[i * 2 + 1] - sub), false);
// c Increment lengthA by 1.
// d If lengthA == lim, return A.
if (++resultLength == limit)
@@ -1030,7 +1046,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec)
if (separatorValue.isUndefined()) {
// a. Call the [[DefineOwnProperty]] internal method of A with arguments "0",
// Property Descriptor {[[Value]]: S, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false.
- result->methodTable()->putByIndex(result, exec, 0, jsStringWithReuse(exec, thisValue, input));
+ result->putDirectIndex(exec, 0, jsStringWithReuse(exec, thisValue, input), false);
// b. Return A.
return JSValue::encode(result);
}
@@ -1043,7 +1059,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec)
// Property Descriptor {[[Value]]: S, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false.
// d. Return A.
if (!separator.isEmpty())
- result->methodTable()->putByIndex(result, exec, 0, jsStringWithReuse(exec, thisValue, input));
+ result->putDirectIndex(exec, 0, jsStringWithReuse(exec, thisValue, input), false);
return JSValue::encode(result);
}
@@ -1054,7 +1070,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec)
ASSERT(limit);
do {
- result->methodTable()->putByIndex(result, exec, position, jsSingleCharacterSubstring(exec, input, position));
+ result->putDirectIndex(exec, position, jsSingleCharacterSubstring(exec, input, position), false);
} while (++position < limit);
return JSValue::encode(result);
@@ -1071,7 +1087,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->methodTable()->putByIndex(result, exec, resultLength, jsSubstring(exec, input, position, matchPosition - position));
+ result->putDirectIndex(exec, resultLength, jsSubstring(exec, input, position, matchPosition - position), false);
// 3. Increment lengthA by 1.
// 4. If lengthA == lim, return A.
if (++resultLength == limit)
@@ -1087,7 +1103,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->methodTable()->putByIndex(result, exec, resultLength++, jsSubstring(exec, input, position, input.length() - position));
+ result->putDirectIndex(exec, resultLength++, jsSubstring(exec, input, position, input.length() - position), false);
// 16. Return A.
return JSValue::encode(result);
diff --git a/Source/JavaScriptCore/runtime/SymbolTable.h b/Source/JavaScriptCore/runtime/SymbolTable.h
index 81731222b..f540a12c7 100644
--- a/Source/JavaScriptCore/runtime/SymbolTable.h
+++ b/Source/JavaScriptCore/runtime/SymbolTable.h
@@ -125,7 +125,7 @@ namespace JSC {
public:
static PassRefPtr<SharedSymbolTable> create() { return adoptRef(new SharedSymbolTable); }
private:
- SharedSymbolTable() { deprecatedTurnOffVerifier(); }
+ SharedSymbolTable() { turnOffVerifier(); }
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/WriteBarrier.h b/Source/JavaScriptCore/runtime/WriteBarrier.h
index 7e9db12fb..05f3bc5bb 100644
--- a/Source/JavaScriptCore/runtime/WriteBarrier.h
+++ b/Source/JavaScriptCore/runtime/WriteBarrier.h
@@ -30,7 +30,7 @@
#include "HandleTypes.h"
#include "Heap.h"
#include "SamplingCounter.h"
-#include "TypeTraits.h"
+#include <wtf/TypeTraits.h>
namespace JSC {
diff --git a/Source/JavaScriptCore/tests/mozilla/ecma/Array/15.4.5.1-1.js b/Source/JavaScriptCore/tests/mozilla/ecma/Array/15.4.5.1-1.js
index e57408b03..71a45e66e 100644
--- a/Source/JavaScriptCore/tests/mozilla/ecma/Array/15.4.5.1-1.js
+++ b/Source/JavaScriptCore/tests/mozilla/ecma/Array/15.4.5.1-1.js
@@ -104,6 +104,8 @@ function getTestCases() {
for ( var i = 0X0020, TEST_STRING = "var A = new Array( " ; i < 0x00ff; i++ ) {
+ if ( i === 0x58 || i === 0x78 ) // x or X - skip testing invalid hex escapes.
+ continue;
TEST_STRING += "\'\\"+ String.fromCharCode( i ) +"\'";
if ( i < 0x00FF - 1 ) {
TEST_STRING += ",";
@@ -112,7 +114,7 @@ function getTestCases() {
}
}
- var LENGTH = 0x00ff - 0x0020;
+ var LENGTH = 0x00ff - 0x0020 - 2; // x & X
array[item++] = new TestCase( SECTION,
TEST_STRING +" A[150] = 'hello'; A[150]",
diff --git a/Source/JavaScriptCore/tests/mozilla/ecma/LexicalConventions/7.7.4.js b/Source/JavaScriptCore/tests/mozilla/ecma/LexicalConventions/7.7.4.js
index 769b81989..d8e26afd5 100644
--- a/Source/JavaScriptCore/tests/mozilla/ecma/LexicalConventions/7.7.4.js
+++ b/Source/JavaScriptCore/tests/mozilla/ecma/LexicalConventions/7.7.4.js
@@ -170,9 +170,9 @@ function getTestCases() {
array[item++] = new TestCase( SECTION, "\\x0F0", String.fromCharCode(15)+"0", "\x0F0" );
// G is out of hex range
-
- array[item++] = new TestCase( SECTION, "\\xG", "xG", "\xG" );
- array[item++] = new TestCase( SECTION, "\\xCG", "xCG", "\xCG" );
+// Invalid hex escapes are syntax error; these are covered in the sputnik test suite.
+// array[item++] = new TestCase( SECTION, "\\xG", "xG", "\xG" );
+// array[item++] = new TestCase( SECTION, "\\xCG", "xCG", "\xCG" );
// DoubleStringCharacter::EscapeSequence::CharacterEscapeSequence::\ NonEscapeCharacter
array[item++] = new TestCase( SECTION, "\\a", "a", "\a" );
@@ -193,7 +193,8 @@ function getTestCases() {
array[item++] = new TestCase( SECTION, "\\u", "u", "\u" );
array[item++] = new TestCase( SECTION, "\\w", "w", "\w" );
- array[item++] = new TestCase( SECTION, "\\x", "x", "\x" );
+// Invalid hex escapes are syntax error; these are covered in the sputnik test suite.
+// array[item++] = new TestCase( SECTION, "\\x", "x", "\x" );
array[item++] = new TestCase( SECTION, "\\y", "y", "\y" );
array[item++] = new TestCase( SECTION, "\\z", "z", "\z" );
array[item++] = new TestCase( SECTION, "\\9", "9", "\9" );
diff --git a/Source/JavaScriptCore/tests/mozilla/ecma/TypeConversion/9.3.1-3.js b/Source/JavaScriptCore/tests/mozilla/ecma/TypeConversion/9.3.1-3.js
index 69407fb5f..083226e5d 100644
--- a/Source/JavaScriptCore/tests/mozilla/ecma/TypeConversion/9.3.1-3.js
+++ b/Source/JavaScriptCore/tests/mozilla/ecma/TypeConversion/9.3.1-3.js
@@ -82,7 +82,7 @@ testcases[tc++] = new TestCase( SECTION,
testcases[tc++] = new TestCase( SECTION,
'- "-0x123456789abcde8"',
- 81985529216486880,
+ NaN,
- "-0x123456789abcde8" );
// Convert some large numbers to string
@@ -474,7 +474,7 @@ testcases[tc++] = new TestCase( SECTION,
testcases[tc++] = new TestCase( SECTION,
"parseInt(\"0022\")",
- 18,
+ 22,
parseInt("0022") );
testcases[tc++] = new TestCase( SECTION,
@@ -664,7 +664,7 @@ testcases[tc++] = new TestCase( SECTION,
testcases[tc++] = new TestCase( SECTION,
"- \"-0x123456789abcde8\"",
- 81985529216486880,
+ NaN,
- "-0x123456789abcde8" );
// the following two tests are not strictly ECMA 1.0
diff --git a/Source/JavaScriptCore/tests/mozilla/ecma_2/RegExp/constructor-001.js b/Source/JavaScriptCore/tests/mozilla/ecma_2/RegExp/constructor-001.js
index be904e576..ceaa39d3d 100644
--- a/Source/JavaScriptCore/tests/mozilla/ecma_2/RegExp/constructor-001.js
+++ b/Source/JavaScriptCore/tests/mozilla/ecma_2/RegExp/constructor-001.js
@@ -40,7 +40,7 @@
AddTestCase(
"(new RegExp()).source",
- "",
+ "(?:)",
re.source );
AddTestCase(
diff --git a/Source/JavaScriptCore/tests/mozilla/ecma_2/RegExp/function-001.js b/Source/JavaScriptCore/tests/mozilla/ecma_2/RegExp/function-001.js
index 67c4f21d4..96c3ccfdc 100644
--- a/Source/JavaScriptCore/tests/mozilla/ecma_2/RegExp/function-001.js
+++ b/Source/JavaScriptCore/tests/mozilla/ecma_2/RegExp/function-001.js
@@ -40,7 +40,7 @@
AddTestCase(
"(new RegExp()).source",
- "",
+ "(?:)",
re.source );
AddTestCase(
diff --git a/Source/JavaScriptCore/tests/mozilla/ecma_2/RegExp/hex-001.js b/Source/JavaScriptCore/tests/mozilla/ecma_2/RegExp/hex-001.js
index 122d59cd3..4a04e944d 100644
--- a/Source/JavaScriptCore/tests/mozilla/ecma_2/RegExp/hex-001.js
+++ b/Source/JavaScriptCore/tests/mozilla/ecma_2/RegExp/hex-001.js
@@ -16,7 +16,8 @@
AddRegExpCases( new RegExp("\x41"), "new RegExp('\\x41')", "A", "A", 1, 0, ["A"] );
AddRegExpCases( new RegExp("\x412"),"new RegExp('\\x412')", "A2", "A2", 1, 0, ["A2"] );
- AddRegExpCases( new RegExp("\x1g"), "new RegExp('\\x1g')", "x1g","x1g", 1, 0, ["x1g"] );
+// Invalid hex escapes are syntax error; these are covered in the sputnik test suite.
+// AddRegExpCases( new RegExp("\x1g"), "new RegExp('\\x1g')", "x1g","x1g", 1, 0, ["x1g"] );
AddRegExpCases( new RegExp("A"), "new RegExp('A')", "\x41", "\\x41", 1, 0, ["A"] );
AddRegExpCases( new RegExp("A"), "new RegExp('A')", "\x412", "\\x412", 1, 0, ["A"] );
diff --git a/Source/JavaScriptCore/tests/mozilla/ecma_2/RegExp/properties-001.js b/Source/JavaScriptCore/tests/mozilla/ecma_2/RegExp/properties-001.js
index 3eb51cbcd..122b94171 100644
--- a/Source/JavaScriptCore/tests/mozilla/ecma_2/RegExp/properties-001.js
+++ b/Source/JavaScriptCore/tests/mozilla/ecma_2/RegExp/properties-001.js
@@ -52,10 +52,6 @@ function AddRegExpCases( re, s, g, i, m, l ) {
// properties
- AddTestCase( re + ".source",
- s,
- re.source );
-
/*
* http://bugzilla.mozilla.org/show_bug.cgi?id=225550 changed
* the behavior of toString() and toSource() on empty regexps.
@@ -63,6 +59,10 @@ function AddRegExpCases( re, s, g, i, m, l ) {
*/
var S = s? s : '(?:)';
+ AddTestCase( re + ".source",
+ S,
+ re.source );
+
AddTestCase( re + ".toString()",
"/" + S +"/" + (g?"g":"") + (i?"i":"") +(m?"m":""),
re.toString() );
diff --git a/Source/JavaScriptCore/tests/mozilla/js1_2/regexp/hexadecimal.js b/Source/JavaScriptCore/tests/mozilla/js1_2/regexp/hexadecimal.js
index 8f68c9ab9..14e555869 100644
--- a/Source/JavaScriptCore/tests/mozilla/js1_2/regexp/hexadecimal.js
+++ b/Source/JavaScriptCore/tests/mozilla/js1_2/regexp/hexadecimal.js
@@ -30,7 +30,7 @@
var SECTION = 'As described in Netscape doc "Whats new in JavaScript 1.2"';
var VERSION = 'no version';
startTest();
- var TITLE = 'RegExp: \x# (hex) ';
+ var TITLE = 'RegExp: \\x# (hex) ';
writeHeaderToLog('Executing script: hexadecimal.js');
writeHeaderToLog( SECTION + " "+ TITLE);
diff --git a/Source/JavaScriptCore/tests/mozilla/js1_6/Array/regress-304828.js b/Source/JavaScriptCore/tests/mozilla/js1_6/Array/regress-304828.js
index 5cab4a75d..fb751e555 100644
--- a/Source/JavaScriptCore/tests/mozilla/js1_6/Array/regress-304828.js
+++ b/Source/JavaScriptCore/tests/mozilla/js1_6/Array/regress-304828.js
@@ -100,7 +100,7 @@ reportCompare('abc', value, summary + ': push');
// pop
value = 'abc';
-expect = 'c';
+expect = 'TypeError: Unable to delete property.';
try
{
actual = Array.prototype.pop.call(value);
@@ -128,7 +128,7 @@ reportCompare('def', value, summary + ': unshift');
// shift
value = 'abc';
-expect = 'a';
+expect = 'TypeError: Unable to delete property.';
try
{
actual = Array.prototype.shift.call(value);
@@ -142,7 +142,7 @@ reportCompare('abc', value, summary + ': shift');
// splice
value = 'abc';
-expect = 'b';
+expect = 'TypeError: Unable to delete property.';
try
{
actual = Array.prototype.splice.call(value, 1, 1) + '';
diff --git a/Source/JavaScriptCore/tools/CodeProfile.cpp b/Source/JavaScriptCore/tools/CodeProfile.cpp
index 349353eb2..beed4b2d5 100644
--- a/Source/JavaScriptCore/tools/CodeProfile.cpp
+++ b/Source/JavaScriptCore/tools/CodeProfile.cpp
@@ -30,7 +30,7 @@
#include "CodeProfiling.h"
#include "LinkBuffer.h"
#include "ProfileTreeNode.h"
-#include "Vector.h"
+#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>
#if PLATFORM(MAC)
diff --git a/Source/JavaScriptCore/tools/TieredMMapArray.h b/Source/JavaScriptCore/tools/TieredMMapArray.h
index fa6e5ae1f..03d9df2b7 100644
--- a/Source/JavaScriptCore/tools/TieredMMapArray.h
+++ b/Source/JavaScriptCore/tools/TieredMMapArray.h
@@ -26,7 +26,7 @@
#ifndef TieredMMapArray_h
#define TieredMMapArray_h
-#include "OSAllocator.h"
+#include <wtf/OSAllocator.h>
namespace JSC {
diff --git a/Source/JavaScriptCore/wscript b/Source/JavaScriptCore/wscript
index d6f1ae899..2093601df 100644
--- a/Source/JavaScriptCore/wscript
+++ b/Source/JavaScriptCore/wscript
@@ -33,7 +33,7 @@ def build(bld):
import Options
- jscore_excludes = ['jsc.cpp', 'ExecutableAllocatorPosix.cpp']
+ jscore_excludes = ['jsc.cpp', 'ExecutableAllocatorPosix.cpp', 'LLIntOffsetsExtractor.cpp']
jscore_excludes.extend(get_excludes(jscore_dir, ['*CF.cpp', '*Symbian.cpp']))
jscore_excludes.extend(get_excludes(jscore_dir, ['*None.cpp']))
diff --git a/Source/JavaScriptCore/wtf/AVLTree.h b/Source/JavaScriptCore/wtf/AVLTree.h
index ec8a63951..f2f82e170 100644
--- a/Source/JavaScriptCore/wtf/AVLTree.h
+++ b/Source/JavaScriptCore/wtf/AVLTree.h
@@ -32,7 +32,7 @@
#ifndef AVL_TREE_H_
#define AVL_TREE_H_
-#include "Assertions.h"
+#include <wtf/Assertions.h>
#include <wtf/FixedArray.h>
namespace WTF {
diff --git a/Source/JavaScriptCore/wtf/Alignment.h b/Source/JavaScriptCore/wtf/Alignment.h
index 9b443efc6..ac780b96e 100644
--- a/Source/JavaScriptCore/wtf/Alignment.h
+++ b/Source/JavaScriptCore/wtf/Alignment.h
@@ -21,7 +21,7 @@
#ifndef WTF_Alignment_h
#define WTF_Alignment_h
-#include "Platform.h"
+#include <wtf/Platform.h>
#include <algorithm>
namespace WTF {
diff --git a/Source/JavaScriptCore/wtf/AlwaysInline.h b/Source/JavaScriptCore/wtf/AlwaysInline.h
index de12ddd90..68b7ae1a8 100644
--- a/Source/JavaScriptCore/wtf/AlwaysInline.h
+++ b/Source/JavaScriptCore/wtf/AlwaysInline.h
@@ -20,4 +20,4 @@
/* This file is no longer necessary, since all the functionality has been moved to Compiler.h. */
-#include "Platform.h"
+#include <wtf/Platform.h>
diff --git a/Source/JavaScriptCore/wtf/ArrayBuffer.h b/Source/JavaScriptCore/wtf/ArrayBuffer.h
index ee95f5bc6..3257df3d0 100644
--- a/Source/JavaScriptCore/wtf/ArrayBuffer.h
+++ b/Source/JavaScriptCore/wtf/ArrayBuffer.h
@@ -88,7 +88,7 @@ public:
void addView(ArrayBufferView*);
void removeView(ArrayBufferView*);
- bool transfer(ArrayBufferContents&, Vector<RefPtr<ArrayBufferView> >& neuteredViews);
+ WTF_EXPORT_PRIVATE bool transfer(ArrayBufferContents&, Vector<RefPtr<ArrayBufferView> >& neuteredViews);
bool isNeutered() { return !m_contents.m_data; }
~ArrayBuffer() { }
diff --git a/Source/JavaScriptCore/wtf/ArrayBufferView.h b/Source/JavaScriptCore/wtf/ArrayBufferView.h
index 24ce25a5e..f314dd56c 100644
--- a/Source/JavaScriptCore/wtf/ArrayBufferView.h
+++ b/Source/JavaScriptCore/wtf/ArrayBufferView.h
@@ -26,7 +26,7 @@
#ifndef ArrayBufferView_h
#define ArrayBufferView_h
-#include "ArrayBuffer.h"
+#include <wtf/ArrayBuffer.h>
#include <algorithm>
#include <limits.h>
@@ -36,7 +36,7 @@
namespace WTF {
-class ArrayBufferView : public RefCounted<ArrayBufferView> {
+class WTF_EXPORT_PRIVATE_RTTI ArrayBufferView : public RefCounted<ArrayBufferView> {
public:
virtual bool isByteArray() const { return false; }
virtual bool isUnsignedByteArray() const { return false; }
@@ -186,6 +186,8 @@ void ArrayBufferView::calculateOffsetAndLength(int start, int end, unsigned arra
end += arraySize;
if (end < 0)
end = 0;
+ if (static_cast<unsigned>(end) > arraySize)
+ end = arraySize;
if (end < start)
end = start;
*offset = static_cast<unsigned>(start);
diff --git a/Source/JavaScriptCore/wtf/Assertions.cpp b/Source/JavaScriptCore/wtf/Assertions.cpp
index 80afcf414..9e744d387 100644
--- a/Source/JavaScriptCore/wtf/Assertions.cpp
+++ b/Source/JavaScriptCore/wtf/Assertions.cpp
@@ -70,8 +70,15 @@ static void vprintf_stderr_common(const char* format, va_list args)
#if PLATFORM(MAC)
if (strstr(format, "%@")) {
CFStringRef cfFormat = CFStringCreateWithCString(NULL, format, kCFStringEncodingUTF8);
- CFStringRef str = CFStringCreateWithFormatAndArguments(NULL, NULL, cfFormat, args);
+#if COMPILER(CLANG)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat-nonliteral"
+#endif
+ CFStringRef str = CFStringCreateWithFormatAndArguments(NULL, NULL, cfFormat, args);
+#if COMPILER(CLANG)
+#pragma clang diagnostic pop
+#endif
int length = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str), kCFStringEncodingUTF8);
char* buffer = (char*)malloc(length + 1);
diff --git a/Source/JavaScriptCore/wtf/Assertions.h b/Source/JavaScriptCore/wtf/Assertions.h
index e7358dccb..14b9091fd 100644
--- a/Source/JavaScriptCore/wtf/Assertions.h
+++ b/Source/JavaScriptCore/wtf/Assertions.h
@@ -42,7 +42,7 @@
http://msdn2.microsoft.com/en-us/library/ms177415(VS.80).aspx
*/
-#include "Platform.h"
+#include <wtf/Platform.h>
#include <stddef.h>
diff --git a/Source/JavaScriptCore/wtf/Atomics.h b/Source/JavaScriptCore/wtf/Atomics.h
index 5e10460c6..d30926897 100644
--- a/Source/JavaScriptCore/wtf/Atomics.h
+++ b/Source/JavaScriptCore/wtf/Atomics.h
@@ -59,9 +59,9 @@
#ifndef Atomics_h
#define Atomics_h
-#include "Platform.h"
-#include "StdLibExtras.h"
-#include "UnusedParam.h"
+#include <wtf/Platform.h>
+#include <wtf/StdLibExtras.h>
+#include <wtf/UnusedParam.h>
#if OS(WINDOWS)
#include <windows.h>
@@ -118,7 +118,11 @@ inline int atomicDecrement(int volatile* addend) { return __gnu_cxx::__exchange_
#endif
+#if COMPILER(GCC) && !COMPILER(CLANG) // Work around a gcc bug
+inline bool weakCompareAndSwap(volatile unsigned* location, unsigned expected, unsigned newValue)
+#else
inline bool weakCompareAndSwap(unsigned* location, unsigned expected, unsigned newValue)
+#endif
{
#if ENABLE(COMPARE_AND_SWAP)
bool result;
@@ -181,7 +185,7 @@ inline bool weakCompareAndSwap(void*volatile* location, void* expected, void* ne
#endif // ENABLE(COMPARE_AND_SWAP)
}
-inline bool weakCompareAndSwap(volatile uintptr_t* location, uintptr_t expected, uintptr_t newValue)
+inline bool weakCompareAndSwapUIntPtr(volatile uintptr_t* location, uintptr_t expected, uintptr_t newValue)
{
return weakCompareAndSwap(reinterpret_cast<void*volatile*>(location), reinterpret_cast<void*>(expected), reinterpret_cast<void*>(newValue));
}
diff --git a/Source/JavaScriptCore/wtf/Bitmap.h b/Source/JavaScriptCore/wtf/Bitmap.h
index d7e2528a3..76a2ca4b3 100644
--- a/Source/JavaScriptCore/wtf/Bitmap.h
+++ b/Source/JavaScriptCore/wtf/Bitmap.h
@@ -19,9 +19,9 @@
#ifndef Bitmap_h
#define Bitmap_h
-#include "Atomics.h"
-#include "FixedArray.h"
-#include "StdLibExtras.h"
+#include <wtf/Atomics.h>
+#include <wtf/FixedArray.h>
+#include <wtf/StdLibExtras.h>
#include <stdint.h>
#include <string.h>
diff --git a/Source/JavaScriptCore/wtf/BoundsCheckedPointer.h b/Source/JavaScriptCore/wtf/BoundsCheckedPointer.h
index d5d42fc1c..1f7caab63 100644
--- a/Source/JavaScriptCore/wtf/BoundsCheckedPointer.h
+++ b/Source/JavaScriptCore/wtf/BoundsCheckedPointer.h
@@ -29,8 +29,8 @@
#ifndef WTF_BoundsCheckedPointer_h
#define WTF_BoundsCheckedPointer_h
-#include "Assertions.h"
-#include "UnusedParam.h"
+#include <wtf/Assertions.h>
+#include <wtf/UnusedParam.h>
namespace WTF {
diff --git a/Source/JavaScriptCore/wtf/CMakeLists.txt b/Source/JavaScriptCore/wtf/CMakeLists.txt
index 63fc59c73..72420128a 100644
--- a/Source/JavaScriptCore/wtf/CMakeLists.txt
+++ b/Source/JavaScriptCore/wtf/CMakeLists.txt
@@ -206,14 +206,9 @@ WEBKIT_INCLUDE_CONFIG_FILES_IF_EXISTS()
WEBKIT_WRAP_SOURCELIST(${WTF_SOURCES})
INCLUDE_DIRECTORIES(${WTF_INCLUDE_DIRECTORIES})
ADD_DEFINITIONS(-DBUILDING_WTF)
-ADD_LIBRARY(${WTF_LIBRARY_NAME} ${WTF_LIBRARY_TYPE} ${WTF_HEADERS} ${WTF_SOURCES})
+ADD_LIBRARY(${WTF_LIBRARY_NAME} STATIC ${WTF_HEADERS} ${WTF_SOURCES})
TARGET_LINK_LIBRARIES(${WTF_LIBRARY_NAME} ${WTF_LIBRARIES})
IF (WTF_LINK_FLAGS)
ADD_TARGET_PROPERTIES(${WTF_LIBRARY_NAME} LINK_FLAGS "${WTF_LINK_FLAGS}")
ENDIF ()
-
-IF (SHARED_CORE)
- SET_TARGET_PROPERTIES(${WTF_LIBRARY_NAME} PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR})
- INSTALL(TARGETS ${WTF_LIBRARY_NAME} DESTINATION lib)
-ENDIF ()
diff --git a/Source/JavaScriptCore/wtf/CheckedArithmetic.h b/Source/JavaScriptCore/wtf/CheckedArithmetic.h
index f90efae41..b18916538 100644
--- a/Source/JavaScriptCore/wtf/CheckedArithmetic.h
+++ b/Source/JavaScriptCore/wtf/CheckedArithmetic.h
@@ -26,8 +26,8 @@
#ifndef CheckedArithmetic_h
#define CheckedArithmetic_h
-#include "Assertions.h"
-#include "TypeTraits.h"
+#include <wtf/Assertions.h>
+#include <wtf/TypeTraits.h>
#include <limits>
#include <stdint.h>
diff --git a/Source/JavaScriptCore/wtf/DateMath.cpp b/Source/JavaScriptCore/wtf/DateMath.cpp
index dc503ca2a..cf601a5ec 100644
--- a/Source/JavaScriptCore/wtf/DateMath.cpp
+++ b/Source/JavaScriptCore/wtf/DateMath.cpp
@@ -935,6 +935,14 @@ double parseDateFromNullTerminatedCharacters(const char* dateString, bool& haveT
}
}
}
+
+ // The year may be after the time but before the time zone.
+ if (isASCIIDigit(*dateString) && year == -1) {
+ if (!parseLong(dateString, &newPosStr, 10, &year))
+ return std::numeric_limits<double>::quiet_NaN();
+ dateString = newPosStr;
+ skipSpacesAndComments(dateString);
+ }
// Don't fail if the time zone is missing.
// Some websites omit the time zone (4275206).
@@ -987,10 +995,9 @@ double parseDateFromNullTerminatedCharacters(const char* dateString, bool& haveT
if (!parseLong(dateString, &newPosStr, 10, &year))
return std::numeric_limits<double>::quiet_NaN();
dateString = newPosStr;
+ skipSpacesAndComments(dateString);
}
- skipSpacesAndComments(dateString);
-
// Trailing garbage
if (*dateString)
return std::numeric_limits<double>::quiet_NaN();
diff --git a/Source/JavaScriptCore/wtf/Deque.h b/Source/JavaScriptCore/wtf/Deque.h
index 18eb10582..47c0dfffa 100644
--- a/Source/JavaScriptCore/wtf/Deque.h
+++ b/Source/JavaScriptCore/wtf/Deque.h
@@ -33,8 +33,8 @@
// FIXME: Could move what Vector and Deque share into a separate file.
// Deque doesn't actually use Vector.
-#include "PassTraits.h"
-#include "Vector.h"
+#include <wtf/PassTraits.h>
+#include <wtf/Vector.h>
namespace WTF {
diff --git a/Source/JavaScriptCore/wtf/ExportMacros.h b/Source/JavaScriptCore/wtf/ExportMacros.h
index a6b3bce5a..4d3219329 100644
--- a/Source/JavaScriptCore/wtf/ExportMacros.h
+++ b/Source/JavaScriptCore/wtf/ExportMacros.h
@@ -30,7 +30,7 @@
#ifndef ExportMacros_h
#define ExportMacros_h
-#include "Platform.h"
+#include <wtf/Platform.h>
// See note in wtf/Platform.h for more info on EXPORT_MACROS.
#if USE(EXPORT_MACROS)
@@ -83,6 +83,14 @@
#define WTF_EXPORT_PRIVATE WTF_IMPORT
#endif
+// wxWebKit uses RTTI because wx itself does, so use a special macro for
+// extra exports it needs.
+#if PLATFORM(WX)
+#define WTF_EXPORT_PRIVATE_RTTI WTF_EXPORT_PRIVATE
+#else
+#define WTF_EXPORT_PRIVATE_RTTI
+#endif
+
#define WTF_EXPORT_HIDDEN WTF_HIDDEN
#define HIDDEN_INLINE WTF_EXPORT_HIDDEN inline
diff --git a/Source/JavaScriptCore/wtf/FastAllocBase.h b/Source/JavaScriptCore/wtf/FastAllocBase.h
index b9ab0cab1..a0804ad3d 100644
--- a/Source/JavaScriptCore/wtf/FastAllocBase.h
+++ b/Source/JavaScriptCore/wtf/FastAllocBase.h
@@ -88,10 +88,10 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
-#include "Assertions.h"
-#include "FastMalloc.h"
-#include "StdLibExtras.h"
-#include "TypeTraits.h"
+#include <wtf/Assertions.h>
+#include <wtf/FastMalloc.h>
+#include <wtf/StdLibExtras.h>
+#include <wtf/TypeTraits.h>
#define WTF_MAKE_FAST_ALLOCATED \
public: \
diff --git a/Source/JavaScriptCore/wtf/FastMalloc.h b/Source/JavaScriptCore/wtf/FastMalloc.h
index b115908ba..871be3756 100644
--- a/Source/JavaScriptCore/wtf/FastMalloc.h
+++ b/Source/JavaScriptCore/wtf/FastMalloc.h
@@ -21,8 +21,8 @@
#ifndef WTF_FastMalloc_h
#define WTF_FastMalloc_h
-#include "Platform.h"
-#include "PossiblyNull.h"
+#include <wtf/Platform.h>
+#include <wtf/PossiblyNull.h>
#include <stdlib.h>
#include <new>
diff --git a/Source/JavaScriptCore/wtf/Float32Array.h b/Source/JavaScriptCore/wtf/Float32Array.h
index 230a768aa..55e61e006 100644
--- a/Source/JavaScriptCore/wtf/Float32Array.h
+++ b/Source/JavaScriptCore/wtf/Float32Array.h
@@ -27,7 +27,7 @@
#ifndef Float32Array_h
#define Float32Array_h
-#include "TypedArrayBase.h"
+#include <wtf/TypedArrayBase.h>
#include <wtf/MathExtras.h>
namespace WTF {
diff --git a/Source/JavaScriptCore/wtf/Float64Array.h b/Source/JavaScriptCore/wtf/Float64Array.h
index 46713556c..30633dbec 100644
--- a/Source/JavaScriptCore/wtf/Float64Array.h
+++ b/Source/JavaScriptCore/wtf/Float64Array.h
@@ -27,7 +27,7 @@
#ifndef Float64Array_h
#define Float64Array_h
-#include "TypedArrayBase.h"
+#include <wtf/TypedArrayBase.h>
#include <wtf/MathExtras.h>
namespace WTF {
diff --git a/Source/JavaScriptCore/wtf/Functional.h b/Source/JavaScriptCore/wtf/Functional.h
index bd0f3e282..bfc813b2a 100644
--- a/Source/JavaScriptCore/wtf/Functional.h
+++ b/Source/JavaScriptCore/wtf/Functional.h
@@ -26,10 +26,10 @@
#ifndef WTF_Functional_h
#define WTF_Functional_h
-#include "Assertions.h"
-#include "PassRefPtr.h"
-#include "RefPtr.h"
-#include "ThreadSafeRefCounted.h"
+#include <wtf/Assertions.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+#include <wtf/ThreadSafeRefCounted.h>
#if PLATFORM(MAC) && COMPILER_SUPPORTS(BLOCKS)
#include <objc/objc-runtime.h>
diff --git a/Source/JavaScriptCore/wtf/HashCountedSet.h b/Source/JavaScriptCore/wtf/HashCountedSet.h
index b97d8c8fd..cafb2649e 100644
--- a/Source/JavaScriptCore/wtf/HashCountedSet.h
+++ b/Source/JavaScriptCore/wtf/HashCountedSet.h
@@ -21,9 +21,9 @@
#ifndef WTF_HashCountedSet_h
#define WTF_HashCountedSet_h
-#include "Assertions.h"
-#include "HashMap.h"
-#include "Vector.h"
+#include <wtf/Assertions.h>
+#include <wtf/HashMap.h>
+#include <wtf/Vector.h>
namespace WTF {
diff --git a/Source/JavaScriptCore/wtf/HashFunctions.h b/Source/JavaScriptCore/wtf/HashFunctions.h
index 2c66a2d9f..808b2b1e5 100644
--- a/Source/JavaScriptCore/wtf/HashFunctions.h
+++ b/Source/JavaScriptCore/wtf/HashFunctions.h
@@ -21,7 +21,7 @@
#ifndef WTF_HashFunctions_h
#define WTF_HashFunctions_h
-#include "RefPtr.h"
+#include <wtf/RefPtr.h>
#include <stdint.h>
namespace WTF {
diff --git a/Source/JavaScriptCore/wtf/HashMap.h b/Source/JavaScriptCore/wtf/HashMap.h
index 13e6d496d..be7e9ebed 100644
--- a/Source/JavaScriptCore/wtf/HashMap.h
+++ b/Source/JavaScriptCore/wtf/HashMap.h
@@ -21,7 +21,7 @@
#ifndef WTF_HashMap_h
#define WTF_HashMap_h
-#include "HashTable.h"
+#include <wtf/HashTable.h>
namespace WTF {
@@ -486,6 +486,6 @@ namespace WTF {
using WTF::HashMap;
-#include "RefPtrHashMap.h"
+#include <wtf/RefPtrHashMap.h>
#endif /* WTF_HashMap_h */
diff --git a/Source/JavaScriptCore/wtf/HashSet.h b/Source/JavaScriptCore/wtf/HashSet.h
index 7fce19348..33cb14daa 100644
--- a/Source/JavaScriptCore/wtf/HashSet.h
+++ b/Source/JavaScriptCore/wtf/HashSet.h
@@ -21,8 +21,8 @@
#ifndef WTF_HashSet_h
#define WTF_HashSet_h
-#include "FastAllocBase.h"
-#include "HashTable.h"
+#include <wtf/FastAllocBase.h>
+#include <wtf/HashTable.h>
namespace WTF {
diff --git a/Source/JavaScriptCore/wtf/HashTable.h b/Source/JavaScriptCore/wtf/HashTable.h
index cbcc09817..05722d9c5 100644
--- a/Source/JavaScriptCore/wtf/HashTable.h
+++ b/Source/JavaScriptCore/wtf/HashTable.h
@@ -22,13 +22,13 @@
#ifndef WTF_HashTable_h
#define WTF_HashTable_h
-#include "Alignment.h"
-#include "Assertions.h"
-#include "FastMalloc.h"
-#include "HashTraits.h"
-#include "StdLibExtras.h"
-#include "Threading.h"
-#include "ValueCheck.h"
+#include <wtf/Alignment.h>
+#include <wtf/Assertions.h>
+#include <wtf/FastMalloc.h>
+#include <wtf/HashTraits.h>
+#include <wtf/StdLibExtras.h>
+#include <wtf/Threading.h>
+#include <wtf/ValueCheck.h>
namespace WTF {
@@ -310,7 +310,8 @@ namespace WTF {
~HashTable()
{
invalidateIterators();
- deallocateTable(m_table, m_tableSize);
+ if (m_table)
+ deallocateTable(m_table, m_tableSize);
#if CHECK_HASHTABLE_USE_AFTER_DESTRUCTION
m_table = (ValueType*)(uintptr_t)0xbbadbeef;
#endif
@@ -979,6 +980,9 @@ namespace WTF {
void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::clear()
{
invalidateIterators();
+ if (!m_table)
+ return;
+
deallocateTable(m_table, m_tableSize);
m_table = 0;
m_tableSize = 0;
@@ -1240,6 +1244,6 @@ namespace WTF {
} // namespace WTF
-#include "HashIterators.h"
+#include <wtf/HashIterators.h>
#endif // WTF_HashTable_h
diff --git a/Source/JavaScriptCore/wtf/HashTraits.h b/Source/JavaScriptCore/wtf/HashTraits.h
index e3783ed42..10f14d1af 100644
--- a/Source/JavaScriptCore/wtf/HashTraits.h
+++ b/Source/JavaScriptCore/wtf/HashTraits.h
@@ -21,9 +21,9 @@
#ifndef WTF_HashTraits_h
#define WTF_HashTraits_h
-#include "HashFunctions.h"
-#include "StdLibExtras.h"
-#include "TypeTraits.h"
+#include <wtf/HashFunctions.h>
+#include <wtf/StdLibExtras.h>
+#include <wtf/TypeTraits.h>
#include <utility>
#include <limits>
diff --git a/Source/JavaScriptCore/wtf/Int16Array.h b/Source/JavaScriptCore/wtf/Int16Array.h
index 34a52de90..df3dcc265 100644
--- a/Source/JavaScriptCore/wtf/Int16Array.h
+++ b/Source/JavaScriptCore/wtf/Int16Array.h
@@ -26,7 +26,7 @@
#ifndef Int16Array_h
#define Int16Array_h
-#include "IntegralTypedArrayBase.h"
+#include <wtf/IntegralTypedArrayBase.h>
namespace WTF {
diff --git a/Source/JavaScriptCore/wtf/Int32Array.h b/Source/JavaScriptCore/wtf/Int32Array.h
index 0b61457b3..f3148c7bc 100644
--- a/Source/JavaScriptCore/wtf/Int32Array.h
+++ b/Source/JavaScriptCore/wtf/Int32Array.h
@@ -27,7 +27,7 @@
#ifndef Int32Array_h
#define Int32Array_h
-#include "IntegralTypedArrayBase.h"
+#include <wtf/IntegralTypedArrayBase.h>
namespace WTF {
diff --git a/Source/JavaScriptCore/wtf/Int8Array.h b/Source/JavaScriptCore/wtf/Int8Array.h
index 6db7b6899..cb5d343e4 100644
--- a/Source/JavaScriptCore/wtf/Int8Array.h
+++ b/Source/JavaScriptCore/wtf/Int8Array.h
@@ -27,7 +27,7 @@
#ifndef Int8Array_h
#define Int8Array_h
-#include "IntegralTypedArrayBase.h"
+#include <wtf/IntegralTypedArrayBase.h>
namespace WTF {
diff --git a/Source/JavaScriptCore/wtf/IntegralTypedArrayBase.h b/Source/JavaScriptCore/wtf/IntegralTypedArrayBase.h
index 48f82a361..f276400f8 100644
--- a/Source/JavaScriptCore/wtf/IntegralTypedArrayBase.h
+++ b/Source/JavaScriptCore/wtf/IntegralTypedArrayBase.h
@@ -27,7 +27,7 @@
#ifndef IntegralTypedArrayBase_h
#define IntegralTypedArrayBase_h
-#include "TypedArrayBase.h"
+#include <wtf/TypedArrayBase.h>
#include <limits>
#include <wtf/MathExtras.h>
diff --git a/Source/JavaScriptCore/wtf/ListHashSet.h b/Source/JavaScriptCore/wtf/ListHashSet.h
index 32bd23832..799466fa9 100644
--- a/Source/JavaScriptCore/wtf/ListHashSet.h
+++ b/Source/JavaScriptCore/wtf/ListHashSet.h
@@ -22,9 +22,9 @@
#ifndef WTF_ListHashSet_h
#define WTF_ListHashSet_h
-#include "HashSet.h"
-#include "OwnPtr.h"
-#include "PassOwnPtr.h"
+#include <wtf/HashSet.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
namespace WTF {
diff --git a/Source/JavaScriptCore/wtf/MainThread.h b/Source/JavaScriptCore/wtf/MainThread.h
index 4839c8117..24200779a 100644
--- a/Source/JavaScriptCore/wtf/MainThread.h
+++ b/Source/JavaScriptCore/wtf/MainThread.h
@@ -30,7 +30,7 @@
#ifndef MainThread_h
#define MainThread_h
-#include "Platform.h"
+#include <wtf/Platform.h>
#include <stdint.h>
diff --git a/Source/JavaScriptCore/wtf/MetaAllocator.cpp b/Source/JavaScriptCore/wtf/MetaAllocator.cpp
index ac6cba8d1..649fbf2bc 100644
--- a/Source/JavaScriptCore/wtf/MetaAllocator.cpp
+++ b/Source/JavaScriptCore/wtf/MetaAllocator.cpp
@@ -64,6 +64,7 @@ MetaAllocatorHandle::MetaAllocatorHandle(MetaAllocator* allocator, void* start,
ASSERT(allocator);
ASSERT(start);
ASSERT(sizeInBytes);
+ turnOffVerifier();
}
MetaAllocatorHandle::~MetaAllocatorHandle()
@@ -169,8 +170,6 @@ PassRefPtr<MetaAllocatorHandle> MetaAllocator::allocate(size_t sizeInBytes, void
#endif
MetaAllocatorHandle* handle = new MetaAllocatorHandle(this, start, sizeInBytes, ownerUID);
- // FIXME: Implement a verifier scheme that groks MetaAllocatorHandles
- handle->deprecatedTurnOffVerifier();
if (UNLIKELY(!!m_tracker))
m_tracker->notify(handle);
diff --git a/Source/JavaScriptCore/wtf/MetaAllocator.h b/Source/JavaScriptCore/wtf/MetaAllocator.h
index ffd55667e..8a73a3b03 100644
--- a/Source/JavaScriptCore/wtf/MetaAllocator.h
+++ b/Source/JavaScriptCore/wtf/MetaAllocator.h
@@ -29,15 +29,15 @@
#ifndef WTF_MetaAllocator_h
#define WTF_MetaAllocator_h
-#include "Assertions.h"
-#include "HashMap.h"
-#include "MetaAllocatorHandle.h"
-#include "Noncopyable.h"
-#include "PageBlock.h"
-#include "RedBlackTree.h"
-#include "RefCounted.h"
-#include "RefPtr.h"
-#include "TCSpinLock.h"
+#include <wtf/Assertions.h>
+#include <wtf/HashMap.h>
+#include <wtf/MetaAllocatorHandle.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/PageBlock.h>
+#include <wtf/RedBlackTree.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+#include <wtf/TCSpinLock.h>
namespace WTF {
@@ -204,6 +204,7 @@ inline MetaAllocator::~MetaAllocator()
freeFreeSpaceNode(node);
node = next;
}
+ m_lock.Finalize();
#ifndef NDEBUG
ASSERT(!m_mallocBalance);
#endif
diff --git a/Source/JavaScriptCore/wtf/Noncopyable.h b/Source/JavaScriptCore/wtf/Noncopyable.h
index 9f93f173b..1e95cbb92 100644
--- a/Source/JavaScriptCore/wtf/Noncopyable.h
+++ b/Source/JavaScriptCore/wtf/Noncopyable.h
@@ -21,7 +21,7 @@
#ifndef WTF_Noncopyable_h
#define WTF_Noncopyable_h
-#include "Compiler.h"
+#include <wtf/Compiler.h>
#if COMPILER_SUPPORTS(CXX_DELETED_FUNCTIONS)
#define WTF_MAKE_NONCOPYABLE(ClassName) \
diff --git a/Source/JavaScriptCore/wtf/OwnArrayPtr.h b/Source/JavaScriptCore/wtf/OwnArrayPtr.h
index 0fc8e71b3..b3d72dfdb 100644
--- a/Source/JavaScriptCore/wtf/OwnArrayPtr.h
+++ b/Source/JavaScriptCore/wtf/OwnArrayPtr.h
@@ -21,10 +21,10 @@
#ifndef WTF_OwnArrayPtr_h
#define WTF_OwnArrayPtr_h
-#include "Assertions.h"
-#include "Noncopyable.h"
-#include "NullPtr.h"
-#include "PassOwnArrayPtr.h"
+#include <wtf/Assertions.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/NullPtr.h>
+#include <wtf/PassOwnArrayPtr.h>
#include <algorithm>
namespace WTF {
diff --git a/Source/JavaScriptCore/wtf/OwnPtr.h b/Source/JavaScriptCore/wtf/OwnPtr.h
index 097967964..326e3fd61 100644
--- a/Source/JavaScriptCore/wtf/OwnPtr.h
+++ b/Source/JavaScriptCore/wtf/OwnPtr.h
@@ -21,10 +21,10 @@
#ifndef WTF_OwnPtr_h
#define WTF_OwnPtr_h
-#include "Assertions.h"
-#include "NullPtr.h"
-#include "OwnPtrCommon.h"
-#include "TypeTraits.h"
+#include <wtf/Assertions.h>
+#include <wtf/NullPtr.h>
+#include <wtf/OwnPtrCommon.h>
+#include <wtf/TypeTraits.h>
#include <algorithm>
#include <memory>
diff --git a/Source/JavaScriptCore/wtf/PackedIntVector.h b/Source/JavaScriptCore/wtf/PackedIntVector.h
index 76fa48a1d..9289eb6b3 100644
--- a/Source/JavaScriptCore/wtf/PackedIntVector.h
+++ b/Source/JavaScriptCore/wtf/PackedIntVector.h
@@ -26,7 +26,7 @@
#ifndef PackedIntVector_h
#define PackedIntVector_h
-#include "BitVector.h"
+#include <wtf/BitVector.h>
namespace WTF {
diff --git a/Source/JavaScriptCore/wtf/ParallelJobs.h b/Source/JavaScriptCore/wtf/ParallelJobs.h
index 92b9c5b5b..0923886ad 100644
--- a/Source/JavaScriptCore/wtf/ParallelJobs.h
+++ b/Source/JavaScriptCore/wtf/ParallelJobs.h
@@ -28,9 +28,9 @@
#ifndef ParallelJobs_h
#define ParallelJobs_h
-#include "Assertions.h"
-#include "Noncopyable.h"
-#include "RefPtr.h"
+#include <wtf/Assertions.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/RefPtr.h>
#include <wtf/Vector.h>
// Usage:
@@ -50,13 +50,13 @@
//
#if ENABLE(THREADING_GENERIC)
-#include "ParallelJobsGeneric.h"
+#include <wtf/ParallelJobsGeneric.h>
#elif ENABLE(THREADING_OPENMP)
-#include "ParallelJobsOpenMP.h"
+#include <wtf/ParallelJobsOpenMP.h>
#elif ENABLE(THREADING_LIBDISPATCH)
-#include "ParallelJobsLibdispatch.h"
+#include <wtf/ParallelJobsLibdispatch.h>
#else
#error "No parallel processing API for ParallelJobs"
diff --git a/Source/JavaScriptCore/wtf/PassOwnArrayPtr.h b/Source/JavaScriptCore/wtf/PassOwnArrayPtr.h
index 3748f18c6..1db7343de 100644
--- a/Source/JavaScriptCore/wtf/PassOwnArrayPtr.h
+++ b/Source/JavaScriptCore/wtf/PassOwnArrayPtr.h
@@ -26,9 +26,9 @@
#ifndef WTF_PassOwnArrayPtr_h
#define WTF_PassOwnArrayPtr_h
-#include "Assertions.h"
-#include "NullPtr.h"
-#include "TypeTraits.h"
+#include <wtf/Assertions.h>
+#include <wtf/NullPtr.h>
+#include <wtf/TypeTraits.h>
namespace WTF {
diff --git a/Source/JavaScriptCore/wtf/PassOwnPtr.h b/Source/JavaScriptCore/wtf/PassOwnPtr.h
index 262ac3bfe..5ebf83d65 100644
--- a/Source/JavaScriptCore/wtf/PassOwnPtr.h
+++ b/Source/JavaScriptCore/wtf/PassOwnPtr.h
@@ -26,10 +26,10 @@
#ifndef WTF_PassOwnPtr_h
#define WTF_PassOwnPtr_h
-#include "Assertions.h"
-#include "NullPtr.h"
-#include "OwnPtrCommon.h"
-#include "TypeTraits.h"
+#include <wtf/Assertions.h>
+#include <wtf/NullPtr.h>
+#include <wtf/OwnPtrCommon.h>
+#include <wtf/TypeTraits.h>
namespace WTF {
diff --git a/Source/JavaScriptCore/wtf/PassRefPtr.h b/Source/JavaScriptCore/wtf/PassRefPtr.h
index a13dee794..207721c96 100644
--- a/Source/JavaScriptCore/wtf/PassRefPtr.h
+++ b/Source/JavaScriptCore/wtf/PassRefPtr.h
@@ -21,8 +21,8 @@
#ifndef WTF_PassRefPtr_h
#define WTF_PassRefPtr_h
-#include "AlwaysInline.h"
-#include "NullPtr.h"
+#include <wtf/AlwaysInline.h>
+#include <wtf/NullPtr.h>
namespace WTF {
diff --git a/Source/JavaScriptCore/wtf/PassTraits.h b/Source/JavaScriptCore/wtf/PassTraits.h
index 346273486..9564e3ad3 100644
--- a/Source/JavaScriptCore/wtf/PassTraits.h
+++ b/Source/JavaScriptCore/wtf/PassTraits.h
@@ -29,8 +29,8 @@
#ifndef WTF_PassTraits_h
#define WTF_PassTraits_h
-#include "OwnPtr.h"
-#include "RefPtr.h"
+#include <wtf/OwnPtr.h>
+#include <wtf/RefPtr.h>
// The PassTraits template exists to help optimize (or make possible) use
// of WTF data structures with WTF smart pointers that have a Pass
diff --git a/Source/JavaScriptCore/wtf/Platform.h b/Source/JavaScriptCore/wtf/Platform.h
index 76b11fe88..c374b03c9 100644
--- a/Source/JavaScriptCore/wtf/Platform.h
+++ b/Source/JavaScriptCore/wtf/Platform.h
@@ -29,7 +29,7 @@
#define WTF_Platform_h
/* Include compiler specific macros */
-#include "Compiler.h"
+#include <wtf/Compiler.h>
/* ==== PLATFORM handles OS, operating environment, graphics API, and
CPU. This macro will be phased out in favor of platform adaptation
@@ -295,7 +295,7 @@
#endif /* ARM */
-#if CPU(ARM) || CPU(MIPS) || CPU(SH4)
+#if CPU(ARM) || CPU(MIPS) || CPU(SH4) || CPU(SPARC)
#define WTF_CPU_NEEDS_ALIGNED_ACCESS 1
#endif
@@ -558,6 +558,9 @@
#if defined(ENABLE_VIDEO)
#define ENABLE_VIDEO_TRACK 1
#endif
+#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) && !defined(BUILDING_ON_LION)
+#define HAVE_LAYER_HOSTING_IN_WINDOW_SERVER 1
+#endif
#endif /* PLATFORM(MAC) && !PLATFORM(IOS) */
#if PLATFORM(CHROMIUM) && OS(DARWIN)
@@ -607,8 +610,9 @@
#define ENABLE_JIT 0
#define ENABLE_YARR_JIT 0
#else
- #define ENABLE_CLASSIC_INTERPRETER 1
+ #define ENABLE_CLASSIC_INTERPRETER 0
#define ENABLE_JIT 1
+ #define ENABLE_LLINT 1
#define ENABLE_YARR_JIT 1
#endif
@@ -920,7 +924,7 @@
#define ENABLE_JIT 0
#endif
-/* The JIT is enabled by default on all x86, x64-64, ARM & MIPS platforms. */
+/* The JIT is enabled by default on all x86, x86-64, ARM & MIPS platforms. */
#if !defined(ENABLE_JIT) \
&& (CPU(X86) || CPU(X86_64) || CPU(ARM) || CPU(MIPS)) \
&& (OS(DARWIN) || !COMPILER(GCC) || GCC_VERSION_AT_LEAST(4, 1, 0)) \
@@ -931,7 +935,7 @@
/* On some of the platforms where we have a JIT, we want to also have the
low-level interpreter. */
-#if !defined(ENABLE_LLINT) && ENABLE(JIT) && OS(DARWIN) && (CPU(X86) || CPU(ARM_THUMB2)) && USE(JSVALUE32_64)
+#if !defined(ENABLE_LLINT) && ENABLE(JIT) && OS(DARWIN) && (CPU(X86) || CPU(X86_64) || CPU(ARM_THUMB2))
#define ENABLE_LLINT 1
#endif
@@ -1074,6 +1078,11 @@
#define WTF_USE_ACCELERATED_COMPOSITING 1
#endif
+/* Compositing on the UI-process in WebKit2 */
+#if PLATFORM(QT)
+#define WTF_USE_UI_SIDE_COMPOSITING 1
+#endif
+
#if (PLATFORM(MAC) && !defined(BUILDING_ON_LEOPARD)) || PLATFORM(IOS)
#define WTF_USE_PROTECTION_SPACE_AUTH_CALLBACK 1
#endif
@@ -1098,6 +1107,10 @@
#define WTF_USE_CROSS_PLATFORM_CONTEXT_MENUS 1
#endif
+#if PLATFORM(MAC) && HAVE(ACCESSIBILITY)
+#define WTF_USE_ACCESSIBILITY_CONTEXT_MENUS 1
+#endif
+
/* Geolocation request policy. pre-emptive policy is to acquire user permission before acquiring location.
Client based implementations will have option to choose between pre-emptive and nonpre-emptive permission policy.
pre-emptive permission policy is enabled by default for all client-based implementations. */
@@ -1118,7 +1131,7 @@
#endif
#if ENABLE(GLIB_SUPPORT)
-#include "GTypedefs.h"
+#include <wtf/gobject/GTypedefs.h>
#endif
/* FIXME: This define won't be needed once #27551 is fully landed. However,
@@ -1194,4 +1207,8 @@
#define WTF_USE_WTFURL 0
#endif
+#if !PLATFORM(QT) && !PLATFORM(EFL)
+#define WTF_USE_ZLIB 1
+#endif
+
#endif /* WTF_Platform_h */
diff --git a/Source/JavaScriptCore/wtf/PossiblyNull.h b/Source/JavaScriptCore/wtf/PossiblyNull.h
index 79c4d8200..46a7d713b 100644
--- a/Source/JavaScriptCore/wtf/PossiblyNull.h
+++ b/Source/JavaScriptCore/wtf/PossiblyNull.h
@@ -26,7 +26,7 @@
#ifndef PossiblyNull_h
#define PossiblyNull_h
-#include "Assertions.h"
+#include <wtf/Assertions.h>
namespace WTF {
diff --git a/Source/JavaScriptCore/wtf/RefCounted.h b/Source/JavaScriptCore/wtf/RefCounted.h
index 51c5dc26e..cea1434e1 100644
--- a/Source/JavaScriptCore/wtf/RefCounted.h
+++ b/Source/JavaScriptCore/wtf/RefCounted.h
@@ -21,12 +21,12 @@
#ifndef RefCounted_h
#define RefCounted_h
-#include "Assertions.h"
-#include "FastAllocBase.h"
-#include "ThreadRestrictionVerifier.h"
-#include "Noncopyable.h"
-#include "OwnPtr.h"
-#include "UnusedParam.h"
+#include <wtf/Assertions.h>
+#include <wtf/FastAllocBase.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/ThreadRestrictionVerifier.h>
+#include <wtf/UnusedParam.h>
namespace WTF {
@@ -77,8 +77,15 @@ public:
// Turns off verification. Use of this method is discouraged (instead extend
// ThreadRestrictionVerifier to verify your case).
- // FIXME: remove this method.
- void deprecatedTurnOffVerifier()
+ // NB. It is necessary to call this in the constructor of many objects in
+ // JavaScriptCore, because JavaScriptCore objects may be used from multiple
+ // threads even if the reference counting is done in a racy manner. This is
+ // because a JSC instance may be used from multiple threads so long as all
+ // accesses into that instance are protected by a per-instance lock. It would
+ // be absolutely wrong to prohibit this pattern, and it would be a disastrous
+ // regression to require that the objects within that instance use a thread-
+ // safe version of reference counting.
+ void turnOffVerifier()
{
#ifndef NDEBUG
m_verifier.turnOffVerification();
diff --git a/Source/JavaScriptCore/wtf/RefCountedArray.h b/Source/JavaScriptCore/wtf/RefCountedArray.h
new file mode 100644
index 000000000..2610a69b8
--- /dev/null
+++ b/Source/JavaScriptCore/wtf/RefCountedArray.h
@@ -0,0 +1,165 @@
+/*
+ * 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 RefCountedArray_h
+#define RefCountedArray_h
+
+#include <wtf/FastMalloc.h>
+#include <wtf/StdLibExtras.h>
+#include <wtf/Vector.h>
+
+// This implements a reference counted array for POD** values, which is optimized for:
+// - An empty array only uses one word.
+// - A copy of the array only uses one word (i.e. assignment means aliasing).
+// - The vector can't grow beyond 2^32-1 elements.
+// - In all other regards this has similar space usage to a Vector.
+//
+// ** This could be modified to support non-POD values quite easily. It just
+// hasn't been, so far, because there has been no need. Moreover, even now,
+// it's used for things that aren't quite POD according to the official
+// defintion, such as JSC::Instruction.
+
+namespace WTF {
+
+template<typename T>
+class RefCountedArray {
+public:
+ RefCountedArray()
+ : m_data(0)
+ {
+ }
+
+ RefCountedArray(const RefCountedArray& other)
+ : m_data(other.m_data)
+ {
+ if (m_data)
+ Header::fromPayload(m_data)->refCount++;
+ }
+
+ explicit RefCountedArray(const Vector<T>& other)
+ {
+ if (other.isEmpty()) {
+ m_data = 0;
+ return;
+ }
+
+ m_data = (static_cast<Header*>(fastMalloc(Header::size() + sizeof(T) * other.size())))->payload();
+ Header::fromPayload(m_data)->refCount = 1;
+ Header::fromPayload(m_data)->length = other.size();
+ ASSERT(Header::fromPayload(m_data)->length == other.size());
+ memcpy(m_data, other.begin(), sizeof(T) * other.size());
+ }
+
+ RefCountedArray& operator=(const RefCountedArray& other)
+ {
+ T* oldData = m_data;
+ m_data = other.m_data;
+ if (m_data)
+ Header::fromPayload(m_data)->refCount++;
+
+ if (!oldData)
+ return *this;
+ if (--Header::fromPayload(oldData)->refCount)
+ return *this;
+ fastFree(Header::fromPayload(oldData));
+ return *this;
+ }
+
+ ~RefCountedArray()
+ {
+ if (!m_data)
+ return;
+ if (--Header::fromPayload(m_data)->refCount)
+ return;
+ fastFree(Header::fromPayload(m_data));
+ }
+
+ size_t size() const
+ {
+ if (!m_data)
+ return 0;
+ return Header::fromPayload(m_data)->length;
+ }
+
+ T* data() { return m_data; }
+ T* begin() { return m_data; }
+ T* end()
+ {
+ if (!m_data)
+ return 0;
+ return m_data + Header::fromPayload(m_data)->length;
+ }
+
+ const T* data() const { return m_data; }
+ const T* begin() const { return m_data; }
+ const T* end() const { return const_cast<RefCountedArray*>(this)->end(); }
+
+ T& at(size_t i)
+ {
+ ASSERT(i < size());
+ return begin()[i];
+ }
+
+ const T& at(size_t i) const
+ {
+ ASSERT(i < size());
+ return begin()[i];
+ }
+
+ T& operator[](size_t i) { return at(i); }
+ const T& operator[](size_t i) const { return at(i); }
+
+private:
+ struct Header {
+ unsigned refCount;
+ unsigned length;
+
+ static size_t size()
+ {
+ return (sizeof(Header) + 7) & ~7;
+ }
+
+ T* payload()
+ {
+ char* result = reinterpret_cast<char*>(this) + size();
+ ASSERT(!(bitwise_cast<uintptr_t>(result) & 7));
+ return reinterpret_cast<T*>(result);
+ }
+
+ static Header* fromPayload(T* payload)
+ {
+ return reinterpret_cast_ptr<Header*>(reinterpret_cast<char*>(payload) - size());
+ }
+ };
+
+ T* m_data;
+};
+
+} // namespace WTF
+
+using WTF::RefCountedArray;
+
+#endif // RefCountedArray_h
+
diff --git a/Source/JavaScriptCore/wtf/RefCountedLeakCounter.h b/Source/JavaScriptCore/wtf/RefCountedLeakCounter.h
index 476b1735a..8d894dd91 100644
--- a/Source/JavaScriptCore/wtf/RefCountedLeakCounter.h
+++ b/Source/JavaScriptCore/wtf/RefCountedLeakCounter.h
@@ -21,8 +21,8 @@
#ifndef RefCountedLeakCounter_h
#define RefCountedLeakCounter_h
-#include "Assertions.h"
-#include "Threading.h"
+#include <wtf/Assertions.h>
+#include <wtf/Threading.h>
namespace WTF {
diff --git a/Source/JavaScriptCore/wtf/RefPtr.h b/Source/JavaScriptCore/wtf/RefPtr.h
index ac94993e3..70ab60003 100644
--- a/Source/JavaScriptCore/wtf/RefPtr.h
+++ b/Source/JavaScriptCore/wtf/RefPtr.h
@@ -24,8 +24,8 @@
#define WTF_RefPtr_h
#include <algorithm>
-#include "FastAllocBase.h"
-#include "PassRefPtr.h"
+#include <wtf/FastAllocBase.h>
+#include <wtf/PassRefPtr.h>
namespace WTF {
diff --git a/Source/JavaScriptCore/wtf/RetainPtr.h b/Source/JavaScriptCore/wtf/RetainPtr.h
index 3d4b0c3f9..a3489577a 100644
--- a/Source/JavaScriptCore/wtf/RetainPtr.h
+++ b/Source/JavaScriptCore/wtf/RetainPtr.h
@@ -21,9 +21,9 @@
#ifndef RetainPtr_h
#define RetainPtr_h
-#include "HashTraits.h"
-#include "NullPtr.h"
-#include "TypeTraits.h"
+#include <wtf/HashTraits.h>
+#include <wtf/NullPtr.h>
+#include <wtf/TypeTraits.h>
#include <algorithm>
#if USE(CF)
diff --git a/Source/JavaScriptCore/wtf/SimpleStats.h b/Source/JavaScriptCore/wtf/SimpleStats.h
new file mode 100644
index 000000000..f1fd7e10a
--- /dev/null
+++ b/Source/JavaScriptCore/wtf/SimpleStats.h
@@ -0,0 +1,107 @@
+/*
+ * 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 SimpleStats_h
+#define SimpleStats_h
+
+#include <wtf/MathExtras.h>
+#include <wtf/StdLibExtras.h>
+
+namespace WTF {
+
+// Simple and cheap way of tracking statistics if you're not worried about chopping on
+// the sum of squares (i.e. the sum of squares is unlikely to exceed 2^52).
+class SimpleStats {
+public:
+ SimpleStats()
+ : m_count(0)
+ , m_sum(0)
+ , m_sumOfSquares(0)
+ {
+ }
+
+ void add(double value)
+ {
+ m_count++;
+ m_sum += value;
+ m_sumOfSquares += value * value;
+ }
+
+ bool operator!() const
+ {
+ return !m_count;
+ }
+
+ double count() const
+ {
+ return m_count;
+ }
+
+ double sum() const
+ {
+ return m_sum;
+ }
+
+ double sumOfSquares() const
+ {
+ return m_sumOfSquares;
+ }
+
+ double mean() const
+ {
+ return m_sum / m_count;
+ }
+
+ // NB. This gives a biased variance as it divides by the number of samples rather
+ // than the degrees of freedom. This is fine once the count grows large, which in
+ // our case will happen rather quickly.
+ double variance() const
+ {
+ if (m_count < 2)
+ return 0;
+
+ // Compute <x^2> - <x>^2
+ double secondMoment = m_sumOfSquares / m_count;
+ double firstMoment = m_sum / m_count;
+
+ return secondMoment - firstMoment * firstMoment;
+ }
+
+ // NB. This gives a biased standard deviation. See above.
+ double standardDeviation() const
+ {
+ return sqrt(variance());
+ }
+
+private:
+ double m_count;
+ double m_sum;
+ double m_sumOfSquares;
+};
+
+} // namespace WTF
+
+#endif // SimpleStats_h
+
diff --git a/Source/JavaScriptCore/wtf/Spectrum.h b/Source/JavaScriptCore/wtf/Spectrum.h
index c403eda18..59bc4a29a 100644
--- a/Source/JavaScriptCore/wtf/Spectrum.h
+++ b/Source/JavaScriptCore/wtf/Spectrum.h
@@ -26,8 +26,8 @@
#ifndef Spectrum_h
#define Spectrum_h
-#include "HashMap.h"
-#include "Vector.h"
+#include <wtf/HashMap.h>
+#include <wtf/Vector.h>
#include <algorithm>
namespace WTF {
diff --git a/Source/JavaScriptCore/wtf/StdLibExtras.h b/Source/JavaScriptCore/wtf/StdLibExtras.h
index 2a0a9f950..0387e5b05 100644
--- a/Source/JavaScriptCore/wtf/StdLibExtras.h
+++ b/Source/JavaScriptCore/wtf/StdLibExtras.h
@@ -26,8 +26,8 @@
#ifndef WTF_StdLibExtras_h
#define WTF_StdLibExtras_h
-#include "CheckedArithmetic.h"
-#include "Assertions.h"
+#include <wtf/Assertions.h>
+#include <wtf/CheckedArithmetic.h>
// Use these to declare and define a static local variable (static T;) so that
// it is leaked so that its destructors are not called at exit. Using this
diff --git a/Source/JavaScriptCore/wtf/TCPageMap.h b/Source/JavaScriptCore/wtf/TCPageMap.h
index 99bdc400e..92fe0b065 100644
--- a/Source/JavaScriptCore/wtf/TCPageMap.h
+++ b/Source/JavaScriptCore/wtf/TCPageMap.h
@@ -54,7 +54,7 @@
#endif
#include <string.h>
-#include "Assertions.h"
+#include <wtf/Assertions.h>
// Single-level array
template <int BITS>
diff --git a/Source/JavaScriptCore/wtf/TCSpinLock.h b/Source/JavaScriptCore/wtf/TCSpinLock.h
index 81b7d0cae..7f19b6c25 100644
--- a/Source/JavaScriptCore/wtf/TCSpinLock.h
+++ b/Source/JavaScriptCore/wtf/TCSpinLock.h
@@ -128,6 +128,7 @@ struct TCMalloc_SpinLock {
}
inline void Init() { lockword_ = 0; }
+ inline void Finalize() { }
volatile unsigned int lockword_;
};
@@ -221,6 +222,7 @@ struct TCMalloc_SpinLock {
}
inline void Init() { m_lockword = 0; }
+ inline void Finalize() { }
LONG m_lockword;
};
diff --git a/Source/JavaScriptCore/wtf/TemporaryChange.h b/Source/JavaScriptCore/wtf/TemporaryChange.h
index fe374b194..95df1728b 100644
--- a/Source/JavaScriptCore/wtf/TemporaryChange.h
+++ b/Source/JavaScriptCore/wtf/TemporaryChange.h
@@ -26,7 +26,7 @@
#ifndef TemporaryChange_h
#define TemporaryChange_h
-#include "Noncopyable.h"
+#include <wtf/Noncopyable.h>
namespace WTF {
diff --git a/Source/JavaScriptCore/wtf/ThreadSafeRefCounted.h b/Source/JavaScriptCore/wtf/ThreadSafeRefCounted.h
index 8497b3bc2..44035e547 100644
--- a/Source/JavaScriptCore/wtf/ThreadSafeRefCounted.h
+++ b/Source/JavaScriptCore/wtf/ThreadSafeRefCounted.h
@@ -59,7 +59,7 @@
#ifndef ThreadSafeRefCounted_h
#define ThreadSafeRefCounted_h
-#include "Platform.h"
+#include <wtf/Platform.h>
#include <wtf/Atomics.h>
#include <wtf/DynamicAnnotations.h>
diff --git a/Source/JavaScriptCore/wtf/Threading.h b/Source/JavaScriptCore/wtf/Threading.h
index b5d432681..3e558fc68 100644
--- a/Source/JavaScriptCore/wtf/Threading.h
+++ b/Source/JavaScriptCore/wtf/Threading.h
@@ -59,7 +59,7 @@
#ifndef Threading_h
#define Threading_h
-#include "Platform.h"
+#include <wtf/Platform.h>
#include <stdint.h>
#include <wtf/Assertions.h>
diff --git a/Source/JavaScriptCore/wtf/ThreadingPrimitives.h b/Source/JavaScriptCore/wtf/ThreadingPrimitives.h
index 2ac42c8f1..9ed38bc9f 100644
--- a/Source/JavaScriptCore/wtf/ThreadingPrimitives.h
+++ b/Source/JavaScriptCore/wtf/ThreadingPrimitives.h
@@ -31,7 +31,7 @@
#ifndef ThreadingPrimitives_h
#define ThreadingPrimitives_h
-#include "Platform.h"
+#include <wtf/Platform.h>
#include <wtf/Assertions.h>
#include <wtf/FastAllocBase.h>
diff --git a/Source/JavaScriptCore/wtf/TypeTraits.h b/Source/JavaScriptCore/wtf/TypeTraits.h
index 34e8b79a3..bfed2aa7b 100644
--- a/Source/JavaScriptCore/wtf/TypeTraits.h
+++ b/Source/JavaScriptCore/wtf/TypeTraits.h
@@ -22,7 +22,7 @@
#ifndef TypeTraits_h
#define TypeTraits_h
-#include "Platform.h"
+#include <wtf/Platform.h>
#if (defined(__GLIBCXX__) && (__GLIBCXX__ >= 20070724) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || (defined(_MSC_VER) && (_MSC_VER >= 1600))
#include <type_traits>
diff --git a/Source/JavaScriptCore/wtf/TypedArrayBase.h b/Source/JavaScriptCore/wtf/TypedArrayBase.h
index dba95d55f..7f989198a 100644
--- a/Source/JavaScriptCore/wtf/TypedArrayBase.h
+++ b/Source/JavaScriptCore/wtf/TypedArrayBase.h
@@ -27,8 +27,8 @@
#ifndef TypedArrayBase_h
#define TypedArrayBase_h
-#include "ArrayBuffer.h"
-#include "ArrayBufferView.h"
+#include <wtf/ArrayBuffer.h>
+#include <wtf/ArrayBufferView.h>
namespace WTF {
diff --git a/Source/JavaScriptCore/wtf/Uint16Array.h b/Source/JavaScriptCore/wtf/Uint16Array.h
index 2d0765051..e73c8ddff 100644
--- a/Source/JavaScriptCore/wtf/Uint16Array.h
+++ b/Source/JavaScriptCore/wtf/Uint16Array.h
@@ -27,7 +27,7 @@
#ifndef Uint16Array_h
#define Uint16Array_h
-#include "IntegralTypedArrayBase.h"
+#include <wtf/IntegralTypedArrayBase.h>
namespace WTF {
diff --git a/Source/JavaScriptCore/wtf/Uint32Array.h b/Source/JavaScriptCore/wtf/Uint32Array.h
index 3765f8077..b2a391267 100644
--- a/Source/JavaScriptCore/wtf/Uint32Array.h
+++ b/Source/JavaScriptCore/wtf/Uint32Array.h
@@ -27,7 +27,7 @@
#ifndef Uint32Array_h
#define Uint32Array_h
-#include "IntegralTypedArrayBase.h"
+#include <wtf/IntegralTypedArrayBase.h>
namespace WTF {
diff --git a/Source/JavaScriptCore/wtf/Uint8Array.h b/Source/JavaScriptCore/wtf/Uint8Array.h
index a0959706c..f46ef0fc0 100644
--- a/Source/JavaScriptCore/wtf/Uint8Array.h
+++ b/Source/JavaScriptCore/wtf/Uint8Array.h
@@ -27,7 +27,7 @@
#ifndef Uint8Array_h
#define Uint8Array_h
-#include "IntegralTypedArrayBase.h"
+#include <wtf/IntegralTypedArrayBase.h>
namespace WTF {
diff --git a/Source/JavaScriptCore/wtf/Uint8ClampedArray.h b/Source/JavaScriptCore/wtf/Uint8ClampedArray.h
index f1044091b..2b77dacc3 100644
--- a/Source/JavaScriptCore/wtf/Uint8ClampedArray.h
+++ b/Source/JavaScriptCore/wtf/Uint8ClampedArray.h
@@ -28,7 +28,7 @@
#ifndef Uint8ClampedArray_h
#define Uint8ClampedArray_h
-#include "Uint8Array.h"
+#include <wtf/Uint8Array.h>
namespace WTF {
diff --git a/Source/JavaScriptCore/wtf/UnusedParam.h b/Source/JavaScriptCore/wtf/UnusedParam.h
index 6ff6fd895..4b7234b8d 100644
--- a/Source/JavaScriptCore/wtf/UnusedParam.h
+++ b/Source/JavaScriptCore/wtf/UnusedParam.h
@@ -24,7 +24,7 @@
/* don't use this for C++, it should only be used in plain C files or
ObjC methods, where leaving off the parameter name is not allowed. */
-#include "Platform.h"
+#include <wtf/Platform.h>
#if COMPILER(INTEL) && !OS(WINDOWS) || COMPILER(RVCT)
template<typename T>
diff --git a/Source/JavaScriptCore/wtf/Vector.h b/Source/JavaScriptCore/wtf/Vector.h
index 29bbd37d9..19e6ffb8c 100644
--- a/Source/JavaScriptCore/wtf/Vector.h
+++ b/Source/JavaScriptCore/wtf/Vector.h
@@ -21,13 +21,13 @@
#ifndef WTF_Vector_h
#define WTF_Vector_h
-#include "Alignment.h"
-#include "FastAllocBase.h"
-#include "Noncopyable.h"
-#include "NotFound.h"
-#include "StdLibExtras.h"
-#include "ValueCheck.h"
-#include "VectorTraits.h"
+#include <wtf/Alignment.h>
+#include <wtf/FastAllocBase.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/NotFound.h>
+#include <wtf/StdLibExtras.h>
+#include <wtf/ValueCheck.h>
+#include <wtf/VectorTraits.h>
#include <limits>
#include <utility>
@@ -281,10 +281,14 @@ namespace WTF {
void deallocateBuffer(T* bufferToDeallocate)
{
+ if (!bufferToDeallocate)
+ return;
+
if (m_buffer == bufferToDeallocate) {
m_buffer = 0;
m_capacity = 0;
}
+
fastFree(bufferToDeallocate);
}
diff --git a/Source/JavaScriptCore/wtf/VectorTraits.h b/Source/JavaScriptCore/wtf/VectorTraits.h
index 6777c9ebf..4041217ab 100644
--- a/Source/JavaScriptCore/wtf/VectorTraits.h
+++ b/Source/JavaScriptCore/wtf/VectorTraits.h
@@ -21,9 +21,9 @@
#ifndef WTF_VectorTraits_h
#define WTF_VectorTraits_h
-#include "OwnPtr.h"
-#include "RefPtr.h"
-#include "TypeTraits.h"
+#include <wtf/OwnPtr.h>
+#include <wtf/RefPtr.h>
+#include <wtf/TypeTraits.h>
#include <utility>
#include <memory>
diff --git a/Source/JavaScriptCore/wtf/WTFThreadData.cpp b/Source/JavaScriptCore/wtf/WTFThreadData.cpp
index 241fbe449..ec5de7220 100644
--- a/Source/JavaScriptCore/wtf/WTFThreadData.cpp
+++ b/Source/JavaScriptCore/wtf/WTFThreadData.cpp
@@ -51,4 +51,25 @@ WTFThreadData::~WTFThreadData()
#endif
}
+} // namespace WTF
+
+#if USE(JSC)
+namespace JSC {
+
+IdentifierTable::~IdentifierTable()
+{
+ HashSet<StringImpl*>::iterator end = m_table.end();
+ for (HashSet<StringImpl*>::iterator iter = m_table.begin(); iter != end; ++iter)
+ (*iter)->setIsIdentifier(false);
+}
+
+std::pair<HashSet<StringImpl*>::iterator, bool> IdentifierTable::add(StringImpl* value)
+{
+ std::pair<HashSet<StringImpl*>::iterator, bool> result = m_table.add(value);
+ (*result.first)->setIsIdentifier(true);
+ return result;
}
+
+} // namespace JSC
+#endif
+
diff --git a/Source/JavaScriptCore/wtf/dtoa/double-conversion.h b/Source/JavaScriptCore/wtf/dtoa/double-conversion.h
index 4d6fc2f57..eec956a21 100644
--- a/Source/JavaScriptCore/wtf/dtoa/double-conversion.h
+++ b/Source/JavaScriptCore/wtf/dtoa/double-conversion.h
@@ -28,7 +28,7 @@
#ifndef DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_
#define DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_
-#include "utils.h"
+#include <wtf/dtoa/utils.h>
namespace WTF {
diff --git a/Source/JavaScriptCore/wtf/dtoa/utils.h b/Source/JavaScriptCore/wtf/dtoa/utils.h
index 64e5ad42f..da6e13226 100644
--- a/Source/JavaScriptCore/wtf/dtoa/utils.h
+++ b/Source/JavaScriptCore/wtf/dtoa/utils.h
@@ -28,7 +28,7 @@
#ifndef DOUBLE_CONVERSION_UTILS_H_
#define DOUBLE_CONVERSION_UTILS_H_
-#include "Assertions.h"
+#include <wtf/Assertions.h>
#include <stdlib.h>
#include <string.h>
diff --git a/Source/JavaScriptCore/wtf/gobject/GRefPtr.cpp b/Source/JavaScriptCore/wtf/gobject/GRefPtr.cpp
index 1cd22c532..30df2c9a6 100644
--- a/Source/JavaScriptCore/wtf/gobject/GRefPtr.cpp
+++ b/Source/JavaScriptCore/wtf/gobject/GRefPtr.cpp
@@ -37,6 +37,32 @@ template <> void derefGPtr(GHashTable* ptr)
g_hash_table_unref(ptr);
}
+template <> GMainContext* refGPtr(GMainContext* ptr)
+{
+ if (ptr)
+ g_main_context_ref(ptr);
+ return ptr;
+}
+
+template <> void derefGPtr(GMainContext* ptr)
+{
+ if (ptr)
+ g_main_context_unref(ptr);
+}
+
+template <> GMainLoop* refGPtr(GMainLoop* ptr)
+{
+ if (ptr)
+ g_main_loop_ref(ptr);
+ return ptr;
+}
+
+template <> void derefGPtr(GMainLoop* ptr)
+{
+ if (ptr)
+ g_main_loop_unref(ptr);
+}
+
#if GLIB_CHECK_VERSION(2, 24, 0)
template <> GVariant* refGPtr(GVariant* ptr)
{
diff --git a/Source/JavaScriptCore/wtf/gobject/GRefPtr.h b/Source/JavaScriptCore/wtf/gobject/GRefPtr.h
index 10ebf0753..92acffc0c 100644
--- a/Source/JavaScriptCore/wtf/gobject/GRefPtr.h
+++ b/Source/JavaScriptCore/wtf/gobject/GRefPtr.h
@@ -25,9 +25,8 @@
#if ENABLE(GLIB_SUPPORT)
-#include "AlwaysInline.h"
-#include "GRefPtr.h"
-#include "RefPtr.h"
+#include <wtf/AlwaysInline.h>
+#include <wtf/RefPtr.h>
#include <algorithm>
extern "C" void g_object_unref(gpointer);
@@ -201,6 +200,10 @@ template <typename T> GRefPtr<T> adoptGRef(T* p)
template <> GHashTable* refGPtr(GHashTable* ptr);
template <> void derefGPtr(GHashTable* ptr);
+template <> GMainContext* refGPtr(GMainContext* ptr);
+template <> void derefGPtr(GMainContext* ptr);
+template <> GMainLoop* refGPtr(GMainLoop* ptr);
+template <> void derefGPtr(GMainLoop* ptr);
template <> GVariant* refGPtr(GVariant* ptr);
template <> void derefGPtr(GVariant* ptr);
template <> GSource* refGPtr(GSource* ptr);
diff --git a/Source/JavaScriptCore/wtf/gobject/GTypedefs.h b/Source/JavaScriptCore/wtf/gobject/GTypedefs.h
index cb3842b78..e29250bef 100644
--- a/Source/JavaScriptCore/wtf/gobject/GTypedefs.h
+++ b/Source/JavaScriptCore/wtf/gobject/GTypedefs.h
@@ -51,6 +51,8 @@ typedef struct _GFile GFile;
typedef struct _GHashTable GHashTable;
typedef struct _GInputStream GInputStream;
typedef struct _GList GList;
+typedef struct _GMainContext GMainContext;
+typedef struct _GMainLoop GMainLoop;
typedef struct _GPatternSpec GPatternSpec;
typedef struct _GPollableOutputStream GPollableOutputStream;
typedef struct _GSList GSList;
diff --git a/Source/JavaScriptCore/wtf/gobject/GlibUtilities.h b/Source/JavaScriptCore/wtf/gobject/GlibUtilities.h
index 5577bf58e..ce10a05c8 100644
--- a/Source/JavaScriptCore/wtf/gobject/GlibUtilities.h
+++ b/Source/JavaScriptCore/wtf/gobject/GlibUtilities.h
@@ -20,8 +20,8 @@
#ifndef GlibUtilities_h
#define GlibUtilities_h
-#include "Assertions.h"
-#include "CString.h"
+#include <wtf/Assertions.h>
+#include <wtf/text/CString.h>
CString getCurrentExecutablePath();
diff --git a/Source/JavaScriptCore/wtf/text/AtomicString.h b/Source/JavaScriptCore/wtf/text/AtomicString.h
index b135845fe..e7323f94a 100644
--- a/Source/JavaScriptCore/wtf/text/AtomicString.h
+++ b/Source/JavaScriptCore/wtf/text/AtomicString.h
@@ -21,8 +21,8 @@
#ifndef AtomicString_h
#define AtomicString_h
-#include "AtomicStringImpl.h"
-#include "WTFString.h"
+#include <wtf/text/AtomicStringImpl.h>
+#include <wtf/text/WTFString.h>
// Define 'NO_IMPLICIT_ATOMICSTRING' before including this header,
// to disallow (expensive) implicit String-->AtomicString conversions.
@@ -213,5 +213,5 @@ using WTF::xmlAtom;
using WTF::xmlnsAtom;
#endif
-#include "StringConcatenate.h"
+#include <wtf/text/StringConcatenate.h>
#endif // AtomicString_h
diff --git a/Source/JavaScriptCore/wtf/text/AtomicStringImpl.h b/Source/JavaScriptCore/wtf/text/AtomicStringImpl.h
index 3f0c37606..0716275a8 100644
--- a/Source/JavaScriptCore/wtf/text/AtomicStringImpl.h
+++ b/Source/JavaScriptCore/wtf/text/AtomicStringImpl.h
@@ -21,7 +21,7 @@
#ifndef AtomicStringImpl_h
#define AtomicStringImpl_h
-#include "StringImpl.h"
+#include <wtf/text/StringImpl.h>
namespace WTF {
diff --git a/Source/JavaScriptCore/wtf/text/CString.h b/Source/JavaScriptCore/wtf/text/CString.h
index d43ad4bd7..9abfa70f7 100644
--- a/Source/JavaScriptCore/wtf/text/CString.h
+++ b/Source/JavaScriptCore/wtf/text/CString.h
@@ -26,9 +26,9 @@
#ifndef CString_h
#define CString_h
-#include "PassRefPtr.h"
-#include "RefCounted.h"
-#include "Vector.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
namespace WTF {
diff --git a/Source/JavaScriptCore/wtf/text/StringConcatenate.h b/Source/JavaScriptCore/wtf/text/StringConcatenate.h
index 08d67dcf0..479ed8ca2 100644
--- a/Source/JavaScriptCore/wtf/text/StringConcatenate.h
+++ b/Source/JavaScriptCore/wtf/text/StringConcatenate.h
@@ -27,7 +27,7 @@
#define StringConcatenate_h
#ifndef WTFString_h
-#include "AtomicString.h"
+#include <wtf/text/AtomicString.h>
#endif
// This macro is helpful for testing how many intermediate Strings are created while evaluating an
@@ -960,5 +960,5 @@ String makeString(StringType1 string1, StringType2 string2, StringType3 string3,
using WTF::makeString;
-#include "StringOperators.h"
+#include <wtf/text/StringOperators.h>
#endif
diff --git a/Source/JavaScriptCore/wtf/text/StringHash.h b/Source/JavaScriptCore/wtf/text/StringHash.h
index 1b7a2ee2c..acc97b995 100644
--- a/Source/JavaScriptCore/wtf/text/StringHash.h
+++ b/Source/JavaScriptCore/wtf/text/StringHash.h
@@ -22,8 +22,8 @@
#ifndef StringHash_h
#define StringHash_h
-#include "AtomicString.h"
-#include "WTFString.h"
+#include <wtf/text/AtomicString.h>
+#include <wtf/text/WTFString.h>
#include <wtf/Forward.h>
#include <wtf/HashTraits.h>
#include <wtf/StringHasher.h>
diff --git a/Source/JavaScriptCore/wtf/text/WTFString.h b/Source/JavaScriptCore/wtf/text/WTFString.h
index edc842154..85e223f9e 100644
--- a/Source/JavaScriptCore/wtf/text/WTFString.h
+++ b/Source/JavaScriptCore/wtf/text/WTFString.h
@@ -25,8 +25,8 @@
// This file would be called String.h, but that conflicts with <string.h>
// on systems without case-sensitive file systems.
-#include "ASCIIFastPath.h"
-#include "StringImpl.h"
+#include <wtf/text/ASCIIFastPath.h>
+#include <wtf/text/StringImpl.h>
#ifdef __OBJC__
#include <objc/objc.h>
@@ -646,5 +646,5 @@ using WTF::isSpaceOrNewline;
using WTF::reverseFind;
using WTF::ShouldRoundDecimalPlaces;
-#include "AtomicString.h"
+#include <wtf/text/AtomicString.h>
#endif
diff --git a/Source/JavaScriptCore/wtf/unicode/CharacterNames.h b/Source/JavaScriptCore/wtf/unicode/CharacterNames.h
index 4acb5f0b1..78b7bf7b9 100644
--- a/Source/JavaScriptCore/wtf/unicode/CharacterNames.h
+++ b/Source/JavaScriptCore/wtf/unicode/CharacterNames.h
@@ -26,7 +26,7 @@
#ifndef CharacterNames_h
#define CharacterNames_h
-#include "Unicode.h"
+#include <wtf/unicode/Unicode.h>
namespace WTF {
namespace Unicode {
diff --git a/Source/JavaScriptCore/wtf/unicode/UTF8.h b/Source/JavaScriptCore/wtf/unicode/UTF8.h
index bc2497b72..59f6994be 100644
--- a/Source/JavaScriptCore/wtf/unicode/UTF8.h
+++ b/Source/JavaScriptCore/wtf/unicode/UTF8.h
@@ -26,7 +26,7 @@
#ifndef WTF_UTF8_h
#define WTF_UTF8_h
-#include "Unicode.h"
+#include <wtf/unicode/Unicode.h>
namespace WTF {
namespace Unicode {
diff --git a/Source/JavaScriptCore/wtf/unicode/glib/UnicodeGLib.h b/Source/JavaScriptCore/wtf/unicode/glib/UnicodeGLib.h
index 7bff934ba..8ad532917 100644
--- a/Source/JavaScriptCore/wtf/unicode/glib/UnicodeGLib.h
+++ b/Source/JavaScriptCore/wtf/unicode/glib/UnicodeGLib.h
@@ -25,9 +25,9 @@
#ifndef UnicodeGLib_h
#define UnicodeGLib_h
-#include "GOwnPtr.h"
-#include "ScriptCodesFromICU.h"
-#include "UnicodeMacrosFromICU.h"
+#include <wtf/gobject/GOwnPtr.h>
+#include <wtf/unicode/ScriptCodesFromICU.h>
+#include <wtf/unicode/UnicodeMacrosFromICU.h>
#include <glib.h>
#include <pango/pango.h>
diff --git a/Source/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h b/Source/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h
index e4f39b292..a2d1ad4c1 100644
--- a/Source/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h
+++ b/Source/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h
@@ -23,8 +23,8 @@
#ifndef WTF_UNICODE_QT4_H
#define WTF_UNICODE_QT4_H
-#include "ScriptCodesFromICU.h"
-#include "UnicodeMacrosFromICU.h"
+#include <wtf/unicode/ScriptCodesFromICU.h>
+#include <wtf/unicode/UnicodeMacrosFromICU.h>
#include <QChar>
#include <QString>
diff --git a/Source/JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.h b/Source/JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.h
index af6ff0748..1663fc969 100644
--- a/Source/JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.h
+++ b/Source/JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.h
@@ -24,8 +24,8 @@
#ifndef WTF_UnicodeWinCE_h
#define WTF_UnicodeWinCE_h
-#include "ScriptCodesFromICU.h"
-#include "UnicodeMacrosFromICU.h"
+#include <wtf/unicode/ScriptCodesFromICU.h>
+#include <wtf/unicode/UnicodeMacrosFromICU.h>
#include "ce_unicode.h"
diff --git a/Source/JavaScriptCore/wtf/url/api/ParsedURL.cpp b/Source/JavaScriptCore/wtf/url/api/ParsedURL.cpp
index 3c1519136..f69162a67 100644
--- a/Source/JavaScriptCore/wtf/url/api/ParsedURL.cpp
+++ b/Source/JavaScriptCore/wtf/url/api/ParsedURL.cpp
@@ -33,13 +33,21 @@
namespace WTF {
-ParsedURL::ParsedURL(const URLString& spec)
- : m_spec(spec)
+ParsedURL::ParsedURL(const String& urlString)
+ : m_spec(urlString)
{
// FIXME: Handle non-standard URLs.
- if (spec.string().isEmpty())
+ if (urlString.isEmpty())
return;
- URLParser<UChar>::parseStandardURL(spec.string().characters(), spec.string().length(), m_segments);
+ URLParser<UChar>::parseStandardURL(urlString.characters(), urlString.length(), m_segments);
+}
+
+ParsedURL ParsedURL::isolatedCopy() const
+{
+ ParsedURL copy;
+ copy.m_segments = this->m_segments;
+ copy.m_spec = URLString(this->m_spec.string().isolatedCopy());
+ return copy;
}
String ParsedURL::scheme() const
@@ -82,11 +90,22 @@ String ParsedURL::fragment() const
return segment(m_segments.fragment);
}
+String ParsedURL::baseAsString() const
+{
+ // FIXME: Add WTFURL Implementation.
+ return String();
+}
+
String ParsedURL::segment(const URLComponent& component) const
{
+ ASSERT(isValid());
+
if (!component.isValid())
return String();
- return m_spec.string().substring(component.begin(), component.length());
+
+ String segment = m_spec.string().substring(component.begin(), component.length());
+ ASSERT_WITH_MESSAGE(!segment.isEmpty(), "A valid URL component should not be empty.");
+ return segment;
}
}
diff --git a/Source/JavaScriptCore/wtf/url/api/ParsedURL.h b/Source/JavaScriptCore/wtf/url/api/ParsedURL.h
index 023589564..2bb3330cf 100644
--- a/Source/JavaScriptCore/wtf/url/api/ParsedURL.h
+++ b/Source/JavaScriptCore/wtf/url/api/ParsedURL.h
@@ -28,27 +28,35 @@
#if USE(WTFURL)
-#include "URLSegments.h"
-#include "URLString.h"
+#include <wtf/url/api/URLString.h>
+#include <wtf/url/src/URLSegments.h>
namespace WTF {
class URLComponent;
+// ParsedURL represents a valid URL decomposed by components.
class ParsedURL {
public:
- explicit ParsedURL(const URLString&);
-
// FIXME: Add a method for parsing non-canonicalized URLs.
+ ParsedURL() { };
+ WTF_EXPORT_PRIVATE explicit ParsedURL(const String&);
+
+ WTF_EXPORT_PRIVATE ParsedURL isolatedCopy() const;
+
+ bool isValid() const { return !m_spec.string().isEmpty(); }
+
+ // Return a URL component or a null String if the component is undefined for the URL.
+ WTF_EXPORT_PRIVATE String scheme() const;
+ WTF_EXPORT_PRIVATE String username() const;
+ WTF_EXPORT_PRIVATE String password() const;
+ WTF_EXPORT_PRIVATE String host() const;
+ WTF_EXPORT_PRIVATE String port() const;
+ WTF_EXPORT_PRIVATE String path() const;
+ WTF_EXPORT_PRIVATE String query() const;
+ WTF_EXPORT_PRIVATE String fragment() const;
- String scheme() const;
- String username() const;
- String password() const;
- String host() const;
- String port() const;
- String path() const;
- String query() const;
- String fragment() const;
+ WTF_EXPORT_PRIVATE String baseAsString() const;
URLString spec() { return m_spec; }
diff --git a/Source/JavaScriptCore/wtf/url/api/URLString.h b/Source/JavaScriptCore/wtf/url/api/URLString.h
index 329f51e2f..9ae30d7a9 100644
--- a/Source/JavaScriptCore/wtf/url/api/URLString.h
+++ b/Source/JavaScriptCore/wtf/url/api/URLString.h
@@ -28,7 +28,7 @@
#if USE(WTFURL)
-#include "WTFString.h"
+#include <wtf/text/WTFString.h>
namespace WTF {
diff --git a/Source/JavaScriptCore/wtf/wince/FastMallocWinCE.h b/Source/JavaScriptCore/wtf/wince/FastMallocWinCE.h
index d91a5f2c9..3601249cf 100644
--- a/Source/JavaScriptCore/wtf/wince/FastMallocWinCE.h
+++ b/Source/JavaScriptCore/wtf/wince/FastMallocWinCE.h
@@ -26,7 +26,7 @@
#ifdef __cplusplus
#include <new>
-#include "MemoryManager.h"
+#include <wtf/wince/MemoryManager.h>
extern "C" {
#endif
diff --git a/Source/JavaScriptCore/yarr/Yarr.h b/Source/JavaScriptCore/yarr/Yarr.h
index 3495fc7e4..57a3846c0 100644
--- a/Source/JavaScriptCore/yarr/Yarr.h
+++ b/Source/JavaScriptCore/yarr/Yarr.h
@@ -43,6 +43,7 @@ namespace JSC { namespace Yarr {
#define YarrStackSpaceForBackTrackInfoParentheses 2
static const unsigned quantifyInfinite = UINT_MAX;
+static const unsigned offsetNoMatch = (unsigned)-1;
// The below limit restricts the number of "recursive" match calls in order to
// avoid spending exponential time on complex regular expressions.
@@ -63,7 +64,7 @@ enum YarrCharSize {
};
JS_EXPORT_PRIVATE PassOwnPtr<BytecodePattern> byteCompile(YarrPattern&, BumpPointerAllocator*);
-JS_EXPORT_PRIVATE int interpret(BytecodePattern*, const UString& input, unsigned start, unsigned length, int* output);
+JS_EXPORT_PRIVATE unsigned interpret(BytecodePattern*, const UString& input, unsigned start, unsigned length, unsigned* output);
} } // namespace JSC::Yarr
diff --git a/Source/JavaScriptCore/yarr/YarrInterpreter.cpp b/Source/JavaScriptCore/yarr/YarrInterpreter.cpp
index 4472538e9..743f16048 100644
--- a/Source/JavaScriptCore/yarr/YarrInterpreter.cpp
+++ b/Source/JavaScriptCore/yarr/YarrInterpreter.cpp
@@ -121,7 +121,7 @@ public:
struct ParenthesesDisjunctionContext
{
- ParenthesesDisjunctionContext(int* output, ByteTerm& term)
+ ParenthesesDisjunctionContext(unsigned* output, ByteTerm& term)
: next(0)
{
unsigned firstSubpatternId = term.atom.subpatternId;
@@ -129,7 +129,7 @@ public:
for (unsigned i = 0; i < (numNestedSubpatterns << 1); ++i) {
subpatternBackup[i] = output[(firstSubpatternId << 1) + i];
- output[(firstSubpatternId << 1) + i] = -1;
+ output[(firstSubpatternId << 1) + i] = offsetNoMatch;
}
new (getDisjunctionContext(term)) DisjunctionContext();
@@ -140,7 +140,7 @@ public:
return where;
}
- void restoreOutput(int* output, unsigned firstSubpatternId, unsigned numNestedSubpatterns)
+ void restoreOutput(unsigned* output, unsigned firstSubpatternId, unsigned numNestedSubpatterns)
{
for (unsigned i = 0; i < (numNestedSubpatterns << 1); ++i)
output[(firstSubpatternId << 1) + i] = subpatternBackup[i];
@@ -152,12 +152,12 @@ public:
}
ParenthesesDisjunctionContext* next;
- int subpatternBackup[1];
+ unsigned subpatternBackup[1];
};
- ParenthesesDisjunctionContext* allocParenthesesDisjunctionContext(ByteDisjunction* disjunction, int* output, ByteTerm& term)
+ ParenthesesDisjunctionContext* allocParenthesesDisjunctionContext(ByteDisjunction* disjunction, unsigned* output, ByteTerm& term)
{
- size_t size = sizeof(ParenthesesDisjunctionContext) - sizeof(int) + (term.atom.parenthesesDisjunction->m_numSubpatterns << 1) * sizeof(int) + 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) + disjunction->m_frameSize * sizeof(uintptr_t);
allocatorPool = allocatorPool->ensureCapacity(size);
if (!allocatorPool)
CRASH();
@@ -249,11 +249,11 @@ public:
return input[pos] | input[pos + 1] << 16;
}
- int readChecked(int position)
+ int readChecked(unsigned negativePositionOffest)
{
- ASSERT(position < 0);
- ASSERT(static_cast<unsigned>(-position) <= pos);
- unsigned p = pos + position;
+ if (pos < negativePositionOffest)
+ CRASH();
+ unsigned p = pos - negativePositionOffest;
ASSERT(p < length);
return input[p];
}
@@ -297,33 +297,37 @@ public:
return length;
}
- bool checkInput(int count)
+ bool checkInput(unsigned count)
{
- if ((pos + count) <= length) {
+ if (((pos + count) <= length) && ((pos + count) >= pos)) {
pos += count;
return true;
}
return false;
}
- void uncheckInput(int count)
+ void uncheckInput(unsigned count)
{
+ if (pos < count)
+ CRASH();
pos -= count;
}
- bool atStart(int position)
+ bool atStart(unsigned negativePositionOffest)
{
- return (pos + position) == 0;
+ return pos == negativePositionOffest;
}
- bool atEnd(int position)
+ bool atEnd(unsigned negativePositionOffest)
{
- return (pos + position) == length;
+ if (pos < negativePositionOffest)
+ CRASH();
+ return (pos - negativePositionOffest) == length;
}
- bool isNotAvailableInput(int position)
+ bool isAvailableInput(unsigned offset)
{
- return (pos + position) > length;
+ return (((pos + offset) <= length) && ((pos + offset) >= pos));
}
private:
@@ -353,45 +357,45 @@ public:
return false;
}
- bool checkCharacter(int testChar, int inputPosition)
+ bool checkCharacter(int testChar, unsigned negativeInputOffset)
{
- return testChar == input.readChecked(inputPosition);
+ return testChar == input.readChecked(negativeInputOffset);
}
- bool checkCasedCharacter(int loChar, int hiChar, int inputPosition)
+ bool checkCasedCharacter(int loChar, int hiChar, unsigned negativeInputOffset)
{
- int ch = input.readChecked(inputPosition);
+ int ch = input.readChecked(negativeInputOffset);
return (loChar == ch) || (hiChar == ch);
}
- bool checkCharacterClass(CharacterClass* characterClass, bool invert, int inputPosition)
+ bool checkCharacterClass(CharacterClass* characterClass, bool invert, unsigned negativeInputOffset)
{
- bool match = testCharacterClass(characterClass, input.readChecked(inputPosition));
+ bool match = testCharacterClass(characterClass, input.readChecked(negativeInputOffset));
return invert ? !match : match;
}
- bool tryConsumeBackReference(int matchBegin, int matchEnd, int inputOffset)
+ bool tryConsumeBackReference(int matchBegin, int matchEnd, unsigned negativeInputOffset)
{
- int matchSize = matchEnd - matchBegin;
+ unsigned matchSize = (unsigned)(matchEnd - matchBegin);
if (!input.checkInput(matchSize))
return false;
if (pattern->m_ignoreCase) {
- for (int i = 0; i < matchSize; ++i) {
+ for (unsigned i = 0; i < matchSize; ++i) {
int ch = input.reread(matchBegin + i);
int lo = Unicode::toLower(ch);
int hi = Unicode::toUpper(ch);
- if ((lo != hi) ? (!checkCasedCharacter(lo, hi, inputOffset - matchSize + i)) : (!checkCharacter(ch, inputOffset - matchSize + i))) {
+ if ((lo != hi) ? (!checkCasedCharacter(lo, hi, negativeInputOffset + matchSize - i)) : (!checkCharacter(ch, negativeInputOffset + matchSize - i))) {
input.uncheckInput(matchSize);
return false;
}
}
} else {
- for (int i = 0; i < matchSize; ++i) {
- if (!checkCharacter(input.reread(matchBegin + i), inputOffset - matchSize + i)) {
+ for (unsigned i = 0; i < matchSize; ++i) {
+ if (!checkCharacter(input.reread(matchBegin + i), negativeInputOffset + matchSize - i)) {
input.uncheckInput(matchSize);
return false;
}
@@ -403,7 +407,7 @@ public:
bool matchAssertionBOL(ByteTerm& term)
{
- return (input.atStart(term.inputPosition)) || (pattern->m_multiline && testCharacterClass(pattern->newlineCharacterClass, input.readChecked(term.inputPosition - 1)));
+ return (input.atStart(term.inputPosition)) || (pattern->m_multiline && testCharacterClass(pattern->newlineCharacterClass, input.readChecked(term.inputPosition + 1)));
}
bool matchAssertionEOL(ByteTerm& term)
@@ -416,7 +420,7 @@ public:
bool matchAssertionWordBoundary(ByteTerm& term)
{
- bool prevIsWordchar = !input.atStart(term.inputPosition) && testCharacterClass(pattern->wordcharCharacterClass, input.readChecked(term.inputPosition - 1));
+ bool prevIsWordchar = !input.atStart(term.inputPosition) && testCharacterClass(pattern->wordcharCharacterClass, input.readChecked(term.inputPosition + 1));
bool readIsWordchar;
if (term.inputPosition)
readIsWordchar = !input.atEnd(term.inputPosition) && testCharacterClass(pattern->wordcharCharacterClass, input.readChecked(term.inputPosition));
@@ -446,7 +450,7 @@ public:
case QuantifierNonGreedy:
if ((backTrack->matchAmount < term.atom.quantityCount) && input.checkInput(1)) {
++backTrack->matchAmount;
- if (checkCharacter(term.atom.patternCharacter, term.inputPosition - 1))
+ if (checkCharacter(term.atom.patternCharacter, term.inputPosition + 1))
return true;
}
input.uncheckInput(backTrack->matchAmount);
@@ -475,7 +479,7 @@ public:
case QuantifierNonGreedy:
if ((backTrack->matchAmount < term.atom.quantityCount) && input.checkInput(1)) {
++backTrack->matchAmount;
- if (checkCasedCharacter(term.atom.casedCharacter.lo, term.atom.casedCharacter.hi, term.inputPosition - 1))
+ if (checkCasedCharacter(term.atom.casedCharacter.lo, term.atom.casedCharacter.hi, term.inputPosition + 1))
return true;
}
input.uncheckInput(backTrack->matchAmount);
@@ -493,7 +497,7 @@ public:
switch (term.atom.quantityType) {
case QuantifierFixedCount: {
for (unsigned matchAmount = 0; matchAmount < term.atom.quantityCount; ++matchAmount) {
- if (!checkCharacterClass(term.atom.characterClass, term.invert(), term.inputPosition + matchAmount))
+ if (!checkCharacterClass(term.atom.characterClass, term.invert(), term.inputPosition - matchAmount))
return false;
}
return true;
@@ -502,7 +506,7 @@ public:
case QuantifierGreedy: {
unsigned matchAmount = 0;
while ((matchAmount < term.atom.quantityCount) && input.checkInput(1)) {
- if (!checkCharacterClass(term.atom.characterClass, term.invert(), term.inputPosition - 1)) {
+ if (!checkCharacterClass(term.atom.characterClass, term.invert(), term.inputPosition + 1)) {
input.uncheckInput(1);
break;
}
@@ -542,7 +546,7 @@ public:
case QuantifierNonGreedy:
if ((backTrack->matchAmount < term.atom.quantityCount) && input.checkInput(1)) {
++backTrack->matchAmount;
- if (checkCharacterClass(term.atom.characterClass, term.invert(), term.inputPosition - 1))
+ if (checkCharacterClass(term.atom.characterClass, term.invert(), term.inputPosition + 1))
return true;
}
input.uncheckInput(backTrack->matchAmount);
@@ -557,16 +561,16 @@ public:
ASSERT(term.type == ByteTerm::TypeBackReference);
BackTrackInfoBackReference* backTrack = reinterpret_cast<BackTrackInfoBackReference*>(context->frame + term.frameLocation);
- int matchBegin = output[(term.atom.subpatternId << 1)];
- int matchEnd = output[(term.atom.subpatternId << 1) + 1];
+ unsigned matchBegin = output[(term.atom.subpatternId << 1)];
+ unsigned matchEnd = output[(term.atom.subpatternId << 1) + 1];
// If the end position of the referenced match hasn't set yet then the backreference in the same parentheses where it references to that.
// In this case the result of match is empty string like when it references to a parentheses with zero-width match.
// Eg.: /(a\1)/
- if (matchEnd == -1)
+ if (matchEnd == offsetNoMatch)
return true;
- if (matchBegin == -1)
+ if (matchBegin == offsetNoMatch)
return true;
ASSERT(matchBegin <= matchEnd);
@@ -609,10 +613,10 @@ public:
ASSERT(term.type == ByteTerm::TypeBackReference);
BackTrackInfoBackReference* backTrack = reinterpret_cast<BackTrackInfoBackReference*>(context->frame + term.frameLocation);
- int matchBegin = output[(term.atom.subpatternId << 1)];
- int matchEnd = output[(term.atom.subpatternId << 1) + 1];
+ unsigned matchBegin = output[(term.atom.subpatternId << 1)];
+ unsigned matchEnd = output[(term.atom.subpatternId << 1) + 1];
- if (matchBegin == -1)
+ if (matchBegin == offsetNoMatch)
return false;
ASSERT(matchBegin <= matchEnd);
@@ -704,7 +708,7 @@ public:
if (term.capture()) {
unsigned subpatternId = term.atom.subpatternId;
- output[(subpatternId << 1)] = input.getPos() + term.inputPosition;
+ output[(subpatternId << 1)] = input.getPos() - term.inputPosition;
}
return true;
@@ -736,8 +740,8 @@ public:
if (term.capture()) {
unsigned subpatternId = term.atom.subpatternId;
- output[(subpatternId << 1)] = -1;
- output[(subpatternId << 1) + 1] = -1;
+ output[(subpatternId << 1)] = offsetNoMatch;
+ output[(subpatternId << 1) + 1] = offsetNoMatch;
}
switch (term.atom.quantityType) {
@@ -1194,7 +1198,7 @@ public:
case ByteTerm::TypePatternCharacterOnce:
case ByteTerm::TypePatternCharacterFixed: {
for (unsigned matchAmount = 0; matchAmount < currentTerm().atom.quantityCount; ++matchAmount) {
- if (!checkCharacter(currentTerm().atom.patternCharacter, currentTerm().inputPosition + matchAmount))
+ if (!checkCharacter(currentTerm().atom.patternCharacter, currentTerm().inputPosition - matchAmount))
BACKTRACK();
}
MATCH_NEXT();
@@ -1203,7 +1207,7 @@ public:
BackTrackInfoPatternCharacter* backTrack = reinterpret_cast<BackTrackInfoPatternCharacter*>(context->frame + currentTerm().frameLocation);
unsigned matchAmount = 0;
while ((matchAmount < currentTerm().atom.quantityCount) && input.checkInput(1)) {
- if (!checkCharacter(currentTerm().atom.patternCharacter, currentTerm().inputPosition - 1)) {
+ if (!checkCharacter(currentTerm().atom.patternCharacter, currentTerm().inputPosition + 1)) {
input.uncheckInput(1);
break;
}
@@ -1222,7 +1226,7 @@ public:
case ByteTerm::TypePatternCasedCharacterOnce:
case ByteTerm::TypePatternCasedCharacterFixed: {
for (unsigned matchAmount = 0; matchAmount < currentTerm().atom.quantityCount; ++matchAmount) {
- if (!checkCasedCharacter(currentTerm().atom.casedCharacter.lo, currentTerm().atom.casedCharacter.hi, currentTerm().inputPosition + matchAmount))
+ if (!checkCasedCharacter(currentTerm().atom.casedCharacter.lo, currentTerm().atom.casedCharacter.hi, currentTerm().inputPosition - matchAmount))
BACKTRACK();
}
MATCH_NEXT();
@@ -1231,7 +1235,7 @@ public:
BackTrackInfoPatternCharacter* backTrack = reinterpret_cast<BackTrackInfoPatternCharacter*>(context->frame + currentTerm().frameLocation);
unsigned matchAmount = 0;
while ((matchAmount < currentTerm().atom.quantityCount) && input.checkInput(1)) {
- if (!checkCasedCharacter(currentTerm().atom.casedCharacter.lo, currentTerm().atom.casedCharacter.hi, currentTerm().inputPosition - 1)) {
+ if (!checkCasedCharacter(currentTerm().atom.casedCharacter.lo, currentTerm().atom.casedCharacter.hi, currentTerm().inputPosition + 1)) {
input.uncheckInput(1);
break;
}
@@ -1449,13 +1453,13 @@ public:
return result;
}
- int interpret()
+ unsigned interpret()
{
- if (input.isNotAvailableInput(0))
- return -1;
+ if (!input.isAvailableInput(0))
+ return offsetNoMatch;
for (unsigned i = 0; i < pattern->m_body->m_numSubpatterns + 1; ++i)
- output[i << 1] = -1;
+ output[i << 1] = offsetNoMatch;
allocatorPool = pattern->m_allocator->startAllocator();
if (!allocatorPool)
@@ -1473,11 +1477,11 @@ public:
pattern->m_allocator->stopAllocator();
- ASSERT((result == JSRegExpMatch) == (output[0] != -1));
+ ASSERT((result == JSRegExpMatch) == (output[0] != offsetNoMatch));
return output[0];
}
- Interpreter(BytecodePattern* pattern, int* output, const UString input, unsigned start, unsigned length)
+ Interpreter(BytecodePattern* pattern, unsigned* output, const UString input, unsigned start, unsigned length)
: pattern(pattern)
, output(output)
, input(input, start, length)
@@ -1488,7 +1492,7 @@ public:
private:
BytecodePattern* pattern;
- int* output;
+ unsigned* output;
InputStream input;
BumpPointerPool* allocatorPool;
unsigned remainingMatchCount;
@@ -1533,22 +1537,22 @@ public:
m_bodyDisjunction->terms.append(ByteTerm::UncheckInput(count));
}
- void assertionBOL(int inputPosition)
+ void assertionBOL(unsigned inputPosition)
{
m_bodyDisjunction->terms.append(ByteTerm::BOL(inputPosition));
}
- void assertionEOL(int inputPosition)
+ void assertionEOL(unsigned inputPosition)
{
m_bodyDisjunction->terms.append(ByteTerm::EOL(inputPosition));
}
- void assertionWordBoundary(bool invert, int inputPosition)
+ void assertionWordBoundary(bool invert, unsigned inputPosition)
{
m_bodyDisjunction->terms.append(ByteTerm::WordBoundary(invert, inputPosition));
}
- void atomPatternCharacter(UChar ch, int inputPosition, unsigned frameLocation, Checked<unsigned> quantityCount, QuantifierType quantityType)
+ void atomPatternCharacter(UChar ch, unsigned inputPosition, unsigned frameLocation, Checked<unsigned> quantityCount, QuantifierType quantityType)
{
if (m_pattern.m_ignoreCase) {
UChar lo = Unicode::toLower(ch);
@@ -1563,7 +1567,7 @@ public:
m_bodyDisjunction->terms.append(ByteTerm(ch, inputPosition, frameLocation, quantityCount, quantityType));
}
- void atomCharacterClass(CharacterClass* characterClass, bool invert, int inputPosition, unsigned frameLocation, Checked<unsigned> quantityCount, QuantifierType quantityType)
+ void atomCharacterClass(CharacterClass* characterClass, bool invert, unsigned inputPosition, unsigned frameLocation, Checked<unsigned> quantityCount, QuantifierType quantityType)
{
m_bodyDisjunction->terms.append(ByteTerm(characterClass, invert, inputPosition));
@@ -1572,7 +1576,7 @@ public:
m_bodyDisjunction->terms[m_bodyDisjunction->terms.size() - 1].frameLocation = frameLocation;
}
- void atomBackReference(unsigned subpatternId, int inputPosition, unsigned frameLocation, Checked<unsigned> quantityCount, QuantifierType quantityType)
+ void atomBackReference(unsigned subpatternId, unsigned inputPosition, unsigned frameLocation, Checked<unsigned> quantityCount, QuantifierType quantityType)
{
ASSERT(subpatternId);
@@ -1583,7 +1587,7 @@ public:
m_bodyDisjunction->terms[m_bodyDisjunction->terms.size() - 1].frameLocation = frameLocation;
}
- void atomParenthesesOnceBegin(unsigned subpatternId, bool capture, int inputPosition, unsigned frameLocation, unsigned alternativeFrameLocation)
+ void atomParenthesesOnceBegin(unsigned subpatternId, bool capture, unsigned inputPosition, unsigned frameLocation, unsigned alternativeFrameLocation)
{
int beginTerm = m_bodyDisjunction->terms.size();
@@ -1596,7 +1600,7 @@ public:
m_currentAlternativeIndex = beginTerm + 1;
}
- void atomParenthesesTerminalBegin(unsigned subpatternId, bool capture, int inputPosition, unsigned frameLocation, unsigned alternativeFrameLocation)
+ void atomParenthesesTerminalBegin(unsigned subpatternId, bool capture, unsigned inputPosition, unsigned frameLocation, unsigned alternativeFrameLocation)
{
int beginTerm = m_bodyDisjunction->terms.size();
@@ -1609,7 +1613,7 @@ public:
m_currentAlternativeIndex = beginTerm + 1;
}
- void atomParenthesesSubpatternBegin(unsigned subpatternId, bool capture, int inputPosition, unsigned frameLocation, unsigned alternativeFrameLocation)
+ void atomParenthesesSubpatternBegin(unsigned subpatternId, bool capture, unsigned inputPosition, unsigned frameLocation, unsigned alternativeFrameLocation)
{
// Errrk! - this is a little crazy, we initially generate as a TypeParenthesesSubpatternOnceBegin,
// then fix this up at the end! - simplifying this should make it much clearer.
@@ -1639,7 +1643,7 @@ public:
m_currentAlternativeIndex = beginTerm + 1;
}
- void atomParentheticalAssertionEnd(int inputPosition, unsigned frameLocation, Checked<unsigned> quantityCount, QuantifierType quantityType)
+ void atomParentheticalAssertionEnd(unsigned inputPosition, unsigned frameLocation, Checked<unsigned> quantityCount, QuantifierType quantityType)
{
unsigned beginTerm = popParenthesesStack();
closeAlternative(beginTerm + 1);
@@ -1871,27 +1875,27 @@ public:
switch (term.type) {
case PatternTerm::TypeAssertionBOL:
- assertionBOL(term.inputPosition - currentCountAlreadyChecked);
+ assertionBOL(currentCountAlreadyChecked - term.inputPosition);
break;
case PatternTerm::TypeAssertionEOL:
- assertionEOL(term.inputPosition - currentCountAlreadyChecked);
+ assertionEOL(currentCountAlreadyChecked - term.inputPosition);
break;
case PatternTerm::TypeAssertionWordBoundary:
- assertionWordBoundary(term.invert(), term.inputPosition - currentCountAlreadyChecked);
+ assertionWordBoundary(term.invert(), currentCountAlreadyChecked - term.inputPosition);
break;
case PatternTerm::TypePatternCharacter:
- atomPatternCharacter(term.patternCharacter, term.inputPosition - currentCountAlreadyChecked, term.frameLocation, term.quantityCount, term.quantityType);
+ atomPatternCharacter(term.patternCharacter, currentCountAlreadyChecked - term.inputPosition, term.frameLocation, term.quantityCount, term.quantityType);
break;
case PatternTerm::TypeCharacterClass:
- atomCharacterClass(term.characterClass, term.invert(), term.inputPosition - currentCountAlreadyChecked, term.frameLocation, term.quantityCount, term.quantityType);
+ atomCharacterClass(term.characterClass, term.invert(), currentCountAlreadyChecked- term.inputPosition, term.frameLocation, term.quantityCount, term.quantityType);
break;
case PatternTerm::TypeBackReference:
- atomBackReference(term.backReferenceSubpatternId, term.inputPosition - currentCountAlreadyChecked, term.frameLocation, term.quantityCount, term.quantityType);
+ atomBackReference(term.backReferenceSubpatternId, currentCountAlreadyChecked - term.inputPosition, term.frameLocation, term.quantityCount, term.quantityType);
break;
case PatternTerm::TypeForwardReference:
@@ -1907,17 +1911,17 @@ public:
else
alternativeFrameLocation += YarrStackSpaceForBackTrackInfoParenthesesOnce;
unsigned delegateEndInputOffset = term.inputPosition - currentCountAlreadyChecked;
- atomParenthesesOnceBegin(term.parentheses.subpatternId, term.capture(), delegateEndInputOffset - disjunctionAlreadyCheckedCount, term.frameLocation, alternativeFrameLocation);
+ atomParenthesesOnceBegin(term.parentheses.subpatternId, term.capture(), disjunctionAlreadyCheckedCount - delegateEndInputOffset, term.frameLocation, alternativeFrameLocation);
emitDisjunction(term.parentheses.disjunction, currentCountAlreadyChecked, disjunctionAlreadyCheckedCount);
atomParenthesesOnceEnd(delegateEndInputOffset, term.frameLocation, term.quantityCount, term.quantityType);
} else if (term.parentheses.isTerminal) {
unsigned delegateEndInputOffset = term.inputPosition - currentCountAlreadyChecked;
- atomParenthesesTerminalBegin(term.parentheses.subpatternId, term.capture(), delegateEndInputOffset - disjunctionAlreadyCheckedCount, term.frameLocation, term.frameLocation + YarrStackSpaceForBackTrackInfoParenthesesOnce);
+ atomParenthesesTerminalBegin(term.parentheses.subpatternId, term.capture(), disjunctionAlreadyCheckedCount - delegateEndInputOffset, term.frameLocation, term.frameLocation + YarrStackSpaceForBackTrackInfoParenthesesOnce);
emitDisjunction(term.parentheses.disjunction, currentCountAlreadyChecked, disjunctionAlreadyCheckedCount);
atomParenthesesTerminalEnd(delegateEndInputOffset, term.frameLocation, term.quantityCount, term.quantityType);
} else {
unsigned delegateEndInputOffset = term.inputPosition - currentCountAlreadyChecked;
- atomParenthesesSubpatternBegin(term.parentheses.subpatternId, term.capture(), delegateEndInputOffset - disjunctionAlreadyCheckedCount, term.frameLocation, 0);
+ atomParenthesesSubpatternBegin(term.parentheses.subpatternId, term.capture(), disjunctionAlreadyCheckedCount - delegateEndInputOffset, term.frameLocation, 0);
emitDisjunction(term.parentheses.disjunction, currentCountAlreadyChecked, 0);
atomParenthesesSubpatternEnd(term.parentheses.lastSubpatternId, delegateEndInputOffset, term.frameLocation, term.quantityCount, term.quantityType, term.parentheses.disjunction->m_callFrameSize);
}
@@ -1967,7 +1971,7 @@ PassOwnPtr<BytecodePattern> byteCompile(YarrPattern& pattern, BumpPointerAllocat
return ByteCompiler(pattern).compile(allocator);
}
-int interpret(BytecodePattern* bytecode, const UString& input, unsigned start, unsigned length, int* output)
+unsigned interpret(BytecodePattern* bytecode, const UString& input, unsigned start, unsigned length, unsigned* output)
{
return Interpreter(bytecode, output, input, start, length).interpret();
}
diff --git a/Source/JavaScriptCore/yarr/YarrInterpreter.h b/Source/JavaScriptCore/yarr/YarrInterpreter.h
index eb5fdc6dc..4bb1efc50 100644
--- a/Source/JavaScriptCore/yarr/YarrInterpreter.h
+++ b/Source/JavaScriptCore/yarr/YarrInterpreter.h
@@ -105,7 +105,7 @@ struct ByteTerm {
unsigned frameLocation;
bool m_capture : 1;
bool m_invert : 1;
- int inputPosition;
+ unsigned inputPosition;
ByteTerm(UChar ch, int inputPos, unsigned frameLocation, Checked<unsigned> quantityCount, QuantifierType quantityType)
: frameLocation(frameLocation)
diff --git a/Source/JavaScriptCore/yarr/YarrJIT.cpp b/Source/JavaScriptCore/yarr/YarrJIT.cpp
index cd861ecf3..2269792ec 100644
--- a/Source/JavaScriptCore/yarr/YarrJIT.cpp
+++ b/Source/JavaScriptCore/yarr/YarrJIT.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "YarrJIT.h"
-#include "ASCIICType.h"
+#include <wtf/ASCIICType.h>
#include "LinkBuffer.h"
#include "Yarr.h"
@@ -1748,7 +1748,7 @@ class YarrGenerator : private MacroAssembler {
if (alternative->m_minimumSize)
sub32(Imm32(alternative->m_minimumSize - 1), regT0);
else
- add32(Imm32(1), regT0);
+ add32(TrustedImm32(1), regT0);
store32(regT0, Address(output));
}
}
@@ -1847,7 +1847,7 @@ class YarrGenerator : private MacroAssembler {
if (alternative->m_minimumSize == m_pattern.m_body->m_minimumSize) {
// If the last alternative had the same minimum size as the disjunction,
// just simply increment input pos by 1, no adjustment based on minimum size.
- add32(Imm32(1), index);
+ add32(TrustedImm32(1), index);
} else {
// If the minumum for the last alternative was one greater than than that
// for the disjunction, we're already progressed by 1, nothing to do!
diff --git a/Source/JavaScriptCore/yarr/YarrParser.h b/Source/JavaScriptCore/yarr/YarrParser.h
index e6694560a..1182d7907 100644
--- a/Source/JavaScriptCore/yarr/YarrParser.h
+++ b/Source/JavaScriptCore/yarr/YarrParser.h
@@ -54,6 +54,7 @@ private:
PatternTooLarge,
QuantifierOutOfOrder,
QuantifierWithoutAtom,
+ QuantifierTooLarge,
MissingParentheses,
ParenthesesUnmatched,
ParenthesesTypeInvalid,
@@ -546,6 +547,11 @@ private:
ASSERT(!m_err);
ASSERT(min <= max);
+ if (min == UINT_MAX) {
+ m_err = QuantifierTooLarge;
+ return;
+ }
+
if (lastTokenWasAnAtom)
m_delegate.quantifyAtom(min, max, !tryConsume('?'));
else
@@ -685,6 +691,7 @@ private:
REGEXP_ERROR_PREFIX "regular expression too large",
REGEXP_ERROR_PREFIX "numbers out of order in {} quantifier",
REGEXP_ERROR_PREFIX "nothing to repeat",
+ REGEXP_ERROR_PREFIX "number too large in {} quantifier",
REGEXP_ERROR_PREFIX "missing )",
REGEXP_ERROR_PREFIX "unmatched parentheses",
REGEXP_ERROR_PREFIX "unrecognized character after (?",
@@ -696,7 +703,6 @@ private:
return errorMessages[m_err];
}
-
// Misc helper functions:
typedef unsigned ParseState;